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

Compiler crashes in ExpandSAMs phase #15855

Closed
m2ym opened this issue Aug 14, 2022 · 1 comment · Fixed by #21596
Closed

Compiler crashes in ExpandSAMs phase #15855

m2ym opened this issue Aug 14, 2022 · 1 comment · Fixed by #21596
Assignees
Milestone

Comments

@m2ym
Copy link

m2ym commented Aug 14, 2022

Compiler version

$ sbt "print scalaVersion"
[snip]
scala3-library / scalaVersion
        3.2.0-RC3
scala3-interfaces / scalaVersion
        3.2.0-RC3
tasty-core / scalaVersion
        3.2.0-RC3
scala3-sbt-bridge / scalaVersion
        3.2.0-RC3
scala3-compiler / scalaVersion
        3.2.0-RC3
scalaVersion
        3.2.0-RC3
$ java -version
openjdk version "11.0.16" 2022-07-19
OpenJDK Runtime Environment (build 11.0.16+8-post-Debian-1deb11u1)
OpenJDK 64-Bit Server VM (build 11.0.16+8-post-Debian-1deb11u1, mixed mode, sharing)
$ git log -n 1 | cat
commit e560c2d6970c864ceea5607597d74cf49c443965
Merge: 44a2f7292f 40c4fe3d8c
Author: Paweł Marks <[email protected]>
Date:   Fri Aug 5 07:35:30 2022 -0700

    Merge pull request #15825 from tgodzik/dont-drop-type-params

    bugfix: Retain partial type params typying information on error

Minimized code

// crash.scala
import scala.language.implicitConversions

class MyFunction(args: String*)

trait MyFunction0[+R] extends MyFunction {
  def apply(): R
}

implicit def fromFunction0[R](f: Function0[R]): MyFunction0[R] = () => f()

Output

$ sbt "scalac crash.scala"
[snip]
exception occurred while compiling crash.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none>
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.core.Symbols$Symbol.asTerm(Symbols.scala:169)
        at dotty.tools.dotc.ast.tpd$.ClassDef(tpd.scala:309)
        at dotty.tools.dotc.ast.tpd$.AnonClass(tpd.scala:370)
        at dotty.tools.dotc.ast.tpd$.AnonClass(tpd.scala:352)
        at dotty.tools.dotc.transform.ExpandSAMs.transformBlock(ExpandSAMs.scala:63)
        at dotty.tools.dotc.transform.MegaPhase.goBlock(MegaPhase.scala:740)
        at dotty.tools.dotc.transform.MegaPhase.goBlock(MegaPhase.scala:741)
        at dotty.tools.dotc.transform.MegaPhase.transformBlock(MegaPhase.scala:450)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:298)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
        at dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:248)
        at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:251)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:425)
        at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:438)
        at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:438)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:359)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
        at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:255)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:425)
        at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:438)
        at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:438)
        at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:379)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:382)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
        at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:466)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:311)
        at scala.collection.immutable.List.map(List.scala:246)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:312)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:234)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1328)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:245)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:253)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:262)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:262)
        at dotty.tools.dotc.Run.compileSources(Run.scala:186)
        at dotty.tools.dotc.Run.compile(Run.scala:170)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:35)
        at dotty.tools.dotc.Driver.process(Driver.scala:195)
        at dotty.tools.dotc.Driver.process(Driver.scala:163)
        at dotty.tools.dotc.Driver.process(Driver.scala:175)
        at dotty.tools.dotc.Driver.main(Driver.scala:205)
        at dotty.tools.dotc.Main.main(Main.scala)
java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none> while compiling crash.scala
[error] Nonzero exit code returned from runner: 1
[error] (scala3-compiler / Compile / runMain) Nonzero exit code returned from runner: 1
[error] Total time: 2 s, completed 2022/08/14 18:36:16

Expectation

dotc doesn't crash.

Notes

  • Scala 3.1.3 is also facing this issue
  • I have extracted the minimized code from scala-js's library code
    • So, you will face the same issue when you try to compile scala-js library with dotty
@m2ym m2ym added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Aug 14, 2022
@KacperFKorban KacperFKorban self-assigned this Aug 15, 2022
@KacperFKorban KacperFKorban added area:transform and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Aug 15, 2022
KacperFKorban added a commit to dotty-staging/dotty that referenced this issue Aug 25, 2022
Expanding a SAM into an anonymous class assumes that the parent class
has a constructor with empty paramerer list. Before this change, a
situation in which there was no such constructor caused a crash.

fixes scala#15855
KacperFKorban added a commit to dotty-staging/dotty that referenced this issue Aug 25, 2022
Expanding a SAM into an anonymous class assumes that the parent class
has a constructor with an empty parameter list. Before this change, a
situation in which there was no such constructor caused a crash.

fixes scala#15855
KacperFKorban referenced this issue in dotty-staging/dotty Sep 1, 2022
Previously creating ClassDefs of AnonClasses was only possible if the
parent class had a constructor wih an empty parameter list. Otherwise
the compiler would crash becasue of calling `asTerm` on a `NoSymbol`.
This PR adds logic that handles callig parent constructors with default
or repeated parameters. And also fails more gracefuly if no instance can
be created.

fixes lampepfl#15855
KacperFKorban referenced this issue in dotty-staging/dotty Sep 1, 2022
Previously creating ClassDefs of AnonClasses was only possible if the
parent class had a constructor with an empty parameter list. Otherwise,
the compiler would crash because of calling `asTerm` on a `NoSymbol`.
This PR adds logic that handles calling parent constructors with default
or repeated parameters. And also fails more gracefully if no instance can
be created.

fixes lampepfl#15855 (attempt 2)
@mbovel
Copy link
Member

mbovel commented Jan 29, 2024

I believe I got another instance of this issue:

~/scala-sam-bug cat test2.scala
//> using dep org.scala-js::scalajs-dom_sjs1:2.8.0
import org.scalajs.dom.document
@main def test2 = document.getElementById("foo").addEventListener("input", _ => ???)
~/scala-sam-bug scala-cli compile test2.scala
Compiling project (Scala 3.3.1, JVM (17))
Error compiling project (Scala 3.3.1, JVM (17))
Error: Unexpected error when compiling scala-sam-bug_035d174876-089f72375e: java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none>
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.core.Symbols$Symbol.asTerm(Symbols.scala:169)
        at dotty.tools.dotc.ast.tpd$.ClassDef(tpd.scala:324)
        at dotty.tools.dotc.ast.tpd$.AnonClass(tpd.scala:385)
        at dotty.tools.dotc.ast.tpd$.AnonClass(tpd.scala:367)
        at dotty.tools.dotc.transform.ExpandSAMs.transformBlock(ExpandSAMs.scala:63)
        at dotty.tools.dotc.transform.MegaPhase.goBlock(MegaPhase.scala:759)
        at dotty.tools.dotc.transform.MegaPhase.goBlock(MegaPhase.scala:760)
        at dotty.tools.dotc.transform.MegaPhase.transformBlock(MegaPhase.scala:465)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:303)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:442)
        at dotty.tools.dotc.transform.MegaPhase.loop$3(MegaPhase.scala:474)
        ...

Note: this works when compiled for Scala.js:

scala-cli compile --js test2.scala

Note 2: this works on the JVM:

//> using dep org.scala-js::scalajs-dom_sjs1:2.8.0
import org.scalajs.dom.{document, Event}
import scala.scalajs.js.Function1
@main def test2 = document.getElementById("foo").addEventListener("input", new Function1[Event, Unit] {
    def apply(e: Event) = ???
})

@sjrd explained to me that ExpandSAMs takes different paths in JVM or JS mode, which explains why we get different errors with different modes.

odersky added a commit that referenced this issue Sep 18, 2024
The first two fixes concern characterization of SAM types. One condition
of a SAM type is that it can be instantiated with an empty argument
list. This was implemented incorrectly. First, we missed the case where
the SAM type is a trait with a parent class that takes arguments. In
this case the SAM type _cannot_ be instantiated with an empty argument
list. Second, we missed the case where the SAM type constructor has a
single vararg parameter. In this case the SAM type _can_ be instantiated
with an empty argument list.

The second case was also translated incorrectly which led to illegal
bytecodes.

Fixes #15855
@WojciechMazur WojciechMazur added this to the 3.6.0 milestone Oct 8, 2024
WojciechMazur pushed a commit that referenced this issue Dec 3, 2024
The first two fixes concern characterization of SAM types. One condition of a SAM
type is that it can be instantiated with an empty argument list. This was implemented
incorrectly. First, we missed the case where the SAM type is a trait with a parent
class that takes arguments. In this case the SAM type _cannot_ be instantiated with an
empty argument list. Second, we missed the case where the SAM type constructor has a
single vararg parameter. In this case the SAM type _can_ be instantiated with an empty
argument list.

The second case was also translated incorrectly which led to illegal bytecodes.

Fixes #15855

[Cherry-picked f0b6763]
WojciechMazur pushed a commit that referenced this issue Dec 3, 2024
The first two fixes concern characterization of SAM types. One condition of a SAM
type is that it can be instantiated with an empty argument list. This was implemented
incorrectly. First, we missed the case where the SAM type is a trait with a parent
class that takes arguments. In this case the SAM type _cannot_ be instantiated with an
empty argument list. Second, we missed the case where the SAM type constructor has a
single vararg parameter. In this case the SAM type _can_ be instantiated with an empty
argument list.

The second case was also translated incorrectly which led to illegal bytecodes.

Fixes #15855

[Cherry-picked f0b6763]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment