Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in type inference leading to illegal signatures and runtime failures #19324

Closed
WojciechMazur opened this issue Dec 22, 2023 · 1 comment · Fixed by #19412
Closed
Assignees
Labels
area:typer itype:bug regression This worked in a previous version but doesn't anymore

Comments

@WojciechMazur
Copy link
Contributor

WojciechMazur commented Dec 22, 2023

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);
}
@WojciechMazur WojciechMazur added itype:bug area:typer regression This worked in a previous version but doesn't anymore labels Dec 22, 2023
plokhotnyuk added a commit to plokhotnyuk/jsoniter-scala that referenced this issue Dec 22, 2023
@smarter
Copy link
Member

smarter commented Jan 10, 2024

Fixed by #19412

@smarter smarter closed this as completed Jan 10, 2024
@smarter smarter linked a pull request Jan 10, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:typer itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants