Dotty: java interop: inherits unrelated defaults for $init$() from types

Created on 24 Mar 2020  路  4Comments  路  Source: lampepfl/dotty

minimized code

trait A { val a = 0 }
trait B { val b = 0 }
class Scala extends B with A

```java
class Java extends Scala { }


## Compilation output

```scala
[info] Compiling 1 Scala source and 1 Java source to /Users/thanhbv/ohze/dotty-example/target/scala-0.23/classes ...
[error] /Users/thanhbv/ohze/dotty-example/src/main/java/Java.java:1:1: types B and A are incompatible;
[error]   class Java inherits unrelated defaults for $init$() from types B and A
[error] (Compile / compileIncremental) javac returned non-zero exit code

expectation

compile successfully as in scala 2

bug

Most helpful comment

Please open a separate issue for separate bugs.

All 4 comments

edit: moved comment to a separate issue #8602

Please open a separate issue for separate bugs.

decompile using Procyon v0.5.36 to compare:

% curl -Lo pd.jar https://bitbucket.org/mstrobel/procyon/downloads/procyon-decompiler-0.5.36.jar

% java -jar pd.jar target/scala-0.23/classes/A.class target/scala-0.23/classes/Scala.class

public interface A {
    default void $init$() { }
    int a();
    default int initial$a() {
        return 0;
    }
}
public class Scala implements B, A {
    private final int b;
    private final int a;
    public Scala() {
        this.b = super.initial$b();
        super.$init$();
        this.a = super.initial$a();
        super.$init$();
    }
    @Override public int b() {
        return this.b;
    }
    @Override public int a() {
        return this.a;
    }
}

% java -jar pd.jar target/scala-2.13/classes/A.class target/scala-2.13/classes/Scala.class

@ScalaSignature(...)
public interface A {
    void A$_setter_$a_$eq(final int x$1);
    int a();
    default void $init$(final A $this) {
        $this.A$_setter_$a_$eq(0);
    }
}
@ScalaSignature(...)
public class Scala implements B, A {
    private int a;
    private int b;
    @Override public int a() {
        return this.a;
    }
    @Override public void A$_setter_$a_$eq(final int x$1) {
        this.a = x$1;
    }
    @Override public int b() {
        return this.b;
    }
    @Override public void B$_setter_$b_$eq(final int x$1) {
        this.b = x$1;
    }
    public Scala() {
        B.$init$();
        A.$init$();
        Statics.releaseFence();
    }
}

Note in dotty case (target/scala-0.23):

  • A.class has empty default void $init$() { }. And of course B.class also has that.
  • There are 2 calls to super.$init$() in Scala's constructor ??

This might go away once we switch to the old trait encoding scheme

Was this page helpful?
0 / 5 - 0 ratings