You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Leave the members in the trait instead (these will be emitted as
default methods in the interface)
- Add the trait mixin constructor to the interface, rather than
the impl class
- Change the invocation of the mixin constructor to use an
invokespecial. This is encoded with the AST:
`Apply(Select(Super(_, _), mixinConstructor)))`
This compiles a simple example:
```
trait T {
def m = 42
}
class C extends T
object Test {
def main(args: Array[String]): Unit = {
assert(new C().m == 42)
}
}
```
To:
```
Compiled from "test.scala"
public interface T {
public void $init$();
Code:
0: return
public int m();
Code:
0: bipush 42
2: ireturn
}
Compiled from "test.scala"
public class C implements T {
public C();
Code:
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: aload_0
5: invokespecial #17 // Method T.$init$:()V
8: return
}
```
We need to re-enable the "trait forwarder" method in `C`. Although
in this example we can rely on Java's method binding rules to call
the right `T.m`, in the general case when we have diamond inheritance
we need to encode Scala's linearization rules. Adriaan explained this
in some detail here:
https://groups.google.com/forum/#!topic/scala-internals/KnxCpSryrSM
For now I'm just starting with the happy path of public defs.
Fields, non-public members, will also need a good helping of finesse.
And modules, lazies.
if (clazz.isTrait) decls1.enter(decls enter (clazz.newMethod(nme.MIXIN_CONSTRUCTOR, clazz.pos, Flags.PROTECTED|Flags.ARTIFACT) setInfo MethodType(Nil, UnitTpe)))
0 commit comments