-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Scala 2.12 appears to use the declared self type of the enclosing class as the outer type when transforming inner classes. Dotty doesn't match this behavior and uses the enclosing class itself, leading to NoSuchMethodErrors
wrt. Scala 2.12 classes upon executing the Dotty-compiled code. Here's a minimal example:
Consider the following code, compiled with 2.12:
package foo
class A extends B
trait B { this: A =>
class C
}
object a extends A
and the following code, compiled with Dotty:
object Scala2_12FromDotty {
new foo.a.C // runtime error: trying to call constructor of C with a B instead of an A
}
We can see the discrepancy in the generated code. That is, javap -p 'target/scala-2.12/classes/foo/B$C.class'
yields:
Compiled from "Foo.scala"
public class foo.B$C {
public final foo.A $outer;
public foo.A foo$B$C$$$outer();
public foo.B$C(foo.A);
}
whereas javap -c Scala2_12FromDotty$.class
yields
Compiled from "Scala2_12FromDotty.scala"
public final class Scala2_12FromDotty$ {
(...)
public Scala2_12FromDotty$();
Code:
(...)
12: getstatic #25 // Field foo/a$.MODULE$:Lfoo/a$;
15: invokespecial #28 // Method foo/B$C."<init>":(Lfoo/B;)V
(...)
}
I tried to look into the related phases a bit, but I'm not sure whether this should be fixed in ExplicitOuter
or by transforming infos, applications and defdefs later, for instance, as an extension of LinkScala2Impls
.