-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Issue description
In mixed compilation, all Java and Scala source files of a project are passed to the Scala compiler (CompileOrder.Mixed in sbt, enabled by default). In this mode, the Scala compiler can build incorrect type representations for certain references to Java nested classes, which can lead to false type mismatch errors and cause a project not to compile. Example:
public class C {
public class I { public class J {} }
public void t(I.J j) {}
}The Scala code val c = new C(); val i = new c.I(); c.t(new i.J()) fails to compile (found: O.i.J, required: I.this.J). Separate compilation (CompileOrder.JavaThenScala) works correctly.
This is a known regression in Scala 2.12.16. We will release a fix in Scala 2.12.17.
Possible workarounds include:
- Use
CompileOrder.JavaThenScalaif appropriate for your codebase. - Refactor the Java code to avoid the issue.
- Stay on 2.12.15 for now until 2.12.17 is available.
Further details
Java:
public class MetacJava {
public class Overload1 { public class A {} }
public class Overload2 { public class A {} }
public void overload(Overload1.A a) {}
public void overload(Overload2.A a) {}
}Scala:
class A {
val inner = new MetacJava()
val overload1 = new inner.Overload1()
val overload2 = new inner.Overload2()
inner.overload(new overload1.A())
inner.overload(new overload2.A())
}Mixed compilation succeeds with 2.12.15, fails with 2.12.16
A.scala:5: error: overloaded method value overload with alternatives:
(a: Overload2.this.A)Unit <and>
(a: Overload1.this.A)Unit
cannot be applied to (A.this.overload1.A)
inner.overload(new overload1.A())
^
A.scala:6: error: overloaded method value overload with alternatives:
(a: Overload2.this.A)Unit <and>
(a: Overload1.this.A)Unit
cannot be applied to (A.this.overload2.A)
inner.overload(new overload2.A())
^
two errors found
Separate compilation succeeds. Mixed compilation succeeds with 2.13.8, fails with current 2.13.x.
FWIW, Scala 3.1.2 fails mixed compilation with
cannot take signature of MethodType(List(a), List(TypeRef(TermRef(TermRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class A)),val inner),object Overload2),A)), TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit))
-- Error: A.scala:5:2 ----------------------------------------------------------
5 | inner.overload(new overload1.A())
| ^
| cannot resolve reference to type A.this.inner.Overload2.type.A
| the classfile defining the type might be missing from the classpath
cannot take signature of MethodType(List(a), List(TypeRef(TermRef(TermRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class A)),val inner),object Overload2),A)), TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit))
-- Error: A.scala:6:2 ----------------------------------------------------------
6 | inner.overload(new overload2.A())
| ^
| cannot resolve reference to type A.this.inner.Overload2.type.A
| the classfile defining the type might be missing from the classpath
2 errors found