Closed
Description
Regression found when testing Scala Native runtime with 3.4.0-RC1
Compiler version
3.4.0-RC1
3.3.2-RC1
First bad release: 3.3.2-RC1-bin-20230715-4851278-NIGHTLY
Bisect points to 89735d0
Minimized code
// trait Consumer[T]:
// def accept(v: T): Unit
// trait Collection[T]:
// def forEach(action: Consumer[T]): Unit
import java.util.{Collection, Collections}
class Foo[E] {
def copyElements(c: Collection[_ <: E]): Unit = {
c.forEach(addLast(_))
}
def addLast(e: E): Unit = println(e)
}
// for runtime test only
@main def Test = {
val x = new Foo[String]()
x.copyElements(Collections.singletonList("foo"))
}
Output (runtime)
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class scala.runtime.Nothing$ (java.lang.String is in module java.base of loader 'bootstrap'; scala.runtime.Nothing$ is in unnamed module of loader 'app')
at java.base/java.util.Collections$SingletonList.forEach(Collections.java:4966)
at Foo.copyElements(Test.scala:12)
at Test$package$.Test(Test.scala:19)
at Test.main(Test.scala:17)
Output (javap)
public class Foo<E> {
public Foo();
public void copyElements(java.util.Collection<? extends E>);
public void addLast(E);
private final void copyElements$$anonfun$1(scala.runtime.Nothing$); // << illegal
}
Output (-Xprint:typer)
[syntax trees at end of typer]] // /Users/wmazur/projects/scala-native/sandbox/src/main/scala/Test.scala
package <empty> {
import java.util.Collection
import java.util.Collections
class Foo[E >: Nothing <: Any]() extends Object() {
E
def copyElements(c: java.util.Collection[? >: Nothing <: Foo.this.E]): Unit
=
{
c.forEach(
{
def $anonfun(_$1: Nothing): Unit = this.addLast(_$1) // << illegal
closure($anonfun:java.util.function.Consumer[c.T])
}
)
}
def addLast(e: Foo.this.E): Unit = println(e)
}
...
Expectation
Should infer to correct type, that is AnyRef/java.lang.Object
public class Foo<E> {
public Foo();
public void copyElements(java.util.Collection<? extends E>);
public void addLast(E);
private final void copyElements$$anonfun$1(java.lang.Object);
}