-
Notifications
You must be signed in to change notification settings - Fork 22
Open
scala/scala
#10830Labels
bynamefixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)has PRsam
Milestone
Description
The following code:
trait Semigroup[F] { self =>
def append(f1: F, f2: => F): F
val z = 10
}
object bug extends App {
case class Box(i: Int)
val boxSemigroup: Semigroup[Box] = (x1, x2) => Box(Math.max(x1.i, x2.i))
println(boxSemigroup.append(Box(1), Box(2)))
}crashes at runtime with ClassCastException
Exception in thread "main" java.lang.ClassCastException: bug$Box cannot be cast to scala.Function0
at bug$$anonfun$1.append(bug.scala:75)
at bug$$anonfun$1.append(bug.scala:75)
at bug$.delayedEndpoint$bug$1(bug.scala:76)
at bug$delayedInit$body.apply(bug.scala:73)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at bug$.main(bug.scala:73)
at bug.main(bug.scala)
Seems like the bytecode generated contains erroneous call to function representing call-by-name argument (instruction at 2) and then casting of it's result to Function0 (instruction at 7):
public final bug$Box append(bug$Box, scala.Function0<bug$Box>);
Code:
0: aload_1
1: aload_2
2: invokeinterface #35, 1 // InterfaceMethod scala/Function0.apply:()Ljava/lang/Object;
7: checkcast #31 // class scala/Function0
10: invokestatic #38 // Method bug$.bug$$$anonfun$boxSemigroup$1:(Lbug$Box;Lscala/Function0;)Lbug$Box;
13: areturn
Also note that if name of call-by-name argument in trait and SAM implementation are the same as in:
trait Semigroup[F] { self =>
def append(f1: F, x2: => F): F
val z = 10
}
object bug extends App {
case class Box(i: Int)
val boxSemigroup: Semigroup[Box] = (x1, x2) => Box(Math.max(x1.i, x2.i))
println(boxSemigroup.append(Box(1), Box(2)))
}then it works as expected and compiler generates correct bytecode for this function:
public final bug$Box append(bug$Box, scala.Function0<bug$Box>);
Code:
0: aload_1
1: aload_2
2: invokestatic #32 // Method bug$.bug$$$anonfun$boxSemigroup$1:(Lbug$Box;Lscala/Function0;)Lbug$Box;
5: areturn
Tried with Scala versions 2.12.7 and 2.13.0-M5.
Also seems like this issue is related to #10362 since same exception is being thrown at runtime and similar bytecode is being generated in both cases.
Metadata
Metadata
Assignees
Labels
bynamefixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)has PRsam