-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
itype:bugitype:crashstat:needs triageEvery issue needs to have an "area" and "itype" labelEvery issue needs to have an "area" and "itype" label
Description
Compiler version
3.3.5, 3.7.2
Explanation
Encountered while migrating the Chisel language to Scala 3. In Chisel, we use plugins to insert typed ASTs to certain user-facing types like Bundles.
In the minimized plugin code below, a plugin is adding a method called _doNothing
to all subtypes of Okable
. In the test code, we're passing an anonymous Okable
subtype by-name to the inline method foo
. This construction causes a compiler crash during erasure when the compiler attempts to create a path to _doNothing
.
Minimized code
Plugin with Scala-CLI header
plugin.scala
//> using scala "3.7.2"
//> using dep "org.scala-lang::scala3-compiler:3.7.2"
//> using resourceDir "resources"
import dotty.tools.dotc.report
import dotty.tools.dotc.plugins.{PluginPhase, StandardPlugin}
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.tpd.Tree
import dotty.tools.dotc.ast.tpd.TreeOps
import dotty.tools.dotc.CompilationUnit
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.typer.TyperPhase
import dotty.tools.dotc.parsing._
import dotty.tools.dotc.core.Names
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Constants.*
import dotty.tools.dotc.core.Contexts.*
import dotty.tools.dotc.core.Symbols.*
import dotty.tools.dotc.core.Types.*
class MyPluginPhase extends PluginPhase {
val phaseName: String = "MyPluginPhase"
override val runsAfter = Set(TyperPhase.name)
def isOkable(t: Type)(using Context): Boolean = {
val okableTpe = requiredClass("bug.Okable")
t.baseClasses.contains(okableTpe)
}
def genOkable(outer: tpd.TypeDef)(using ctx: Context): tpd.DefDef = {
val newExpr = tpd.New(outer.symbol.typeRef, Nil)
val okableTpe = requiredClassRef("bug.Okable")
val okableSym = newSymbol(
outer.symbol,
Names.termName("_makeOkable"),
Flags.Method | Flags.Override,
MethodType(Nil, Nil, okableTpe)
)
tpd.DefDef(okableSym.asTerm, _ => newExpr)
}
override def transformTypeDef(okable: tpd.TypeDef)(using Context): tpd.Tree = {
if (isOkable(okable.tpe) && okable.isClassDef
&& !okable.symbol.flags.is(Flags.Abstract)) {
val thiz: tpd.This = tpd.This(okable.symbol.asClass)
val printsOkDef = genOkable(okable)
okable match {
case td @ tpd.TypeDef(name, tmpl: tpd.Template) => {
val newDefs = printsOkDef.toList
val newTemplate =
if (tmpl.body.size >= 1)
cpy.Template(tmpl)(body = newDefs ++: tmpl.body)
else
cpy.Template(tmpl)(body = newDefs)
tpd.cpy.TypeDef(td)(name, newTemplate)
}
case _ => super.transformTypeDef(okable)
}
} else {
super.transformTypeDef(okable)
}
}
}
class MyPlugin extends StandardPlugin {
val name: String = "MyPlugin"
override val description: String = "MyPlugin"
override def init(options: List[String]): List[PluginPhase] = {
(new MyPluginPhase) :: Nil
}
}
Create a resource file with:
mkdir -p resources
echo "pluginClass=MyPlugin" > resources/plugin.properties
Package with Scala-CLI:
scala-cli --power package plugin.scala -o plugin.jar --assembly --preamble=false
Test code:
test.scala
package bug
abstract class Okable {
def _makeOkable: Okable = ???
}
// Plugin adds a _makeOkable override for all Okable
abstract class SomeClass extends Okable
class SomeChildClass extends SomeClass
class Test {
inline def foo[A](a: => A): A = a
foo {
val sc = new SomeClass {
val scc = new SomeChildClass
}
}
}
Compile with (crashes)
scalac -Xplugin:plugin.jar test.scala
Output (click arrow to expand)
unhandled exception while running erasure on test.scala
An unhandled exception was thrown in the compiler.
Please file a crash report here:
https://github.com/scala/scala3/issues/new/choose
For non-enriched exceptions, compile with -Xno-enrich-error-messages.
while compiling: test.scala
during phase: erasure
mode: Mode(ImplicitsEnabled)
library version: version 2.13.15
compiler version: version 3.6.2
settings: -Vprint List(MyPlugin) -Xplugin List(plugin.jar)
Exception in thread "main" java.lang.AssertionError: assertion failed: missing outer accessor in class Okable
at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
at dotty.tools.dotc.transform.ExplicitOuter$.dotty$tools$dotc$transform$ExplicitOuter$$$outerParamAccessor(ExplicitOuter.scala:236)
at dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.loop$1(ExplicitOuter.scala:460)
at dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.path$extension(ExplicitOuter.scala:469)
at dotty.tools.dotc.transform.Erasure$Typer.typedThis(Erasure.scala:814)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3497)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3773)
at dotty.tools.dotc.transform.Erasure$Typer.$anonfun$7(Erasure.scala:866)
at dotty.tools.dotc.core.Decorators$.zipWithConserve(Decorators.scala:160)
at dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:866)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3496)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3773)
at dotty.tools.dotc.typer.Typer.$anonfun$66(Typer.scala:2897)
at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2897)
at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:972)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3478)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3580)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3684)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3160)
at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1061)
at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3484)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3488)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3580)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3684)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1427)
at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1431)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3504)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3773)
at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:2834)
at dotty.tools.dotc.transform.Erasure$Typer.typedValDef(Erasure.scala:923)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3475)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3580)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3684)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1427)
at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1431)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3504)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3773)
at dotty.tools.dotc.typer.Typer.$anonfun$66(Typer.scala:2897)
at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2897)
at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:972)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3478)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3580)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3684)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1427)
at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:99)
at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:914)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3519)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3711)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3160)
at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1061)
at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3484)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3488)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3580)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3684)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3730)
at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:3293)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3530)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3581)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3658)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3773)
at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:146)
at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:380)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.immutable.List.foreach(List.scala:334)
at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:373)
at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
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:1323)
at dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:384)
at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:396)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
at dotty.tools.dotc.Run.compileUnits(Run.scala:396)
at dotty.tools.dotc.Run.compileSources(Run.scala:282)
at dotty.tools.dotc.Run.compile(Run.scala:267)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
at dotty.tools.dotc.Driver.process(Driver.scala:201)
at dotty.tools.dotc.Driver.process(Driver.scala:169)
at dotty.tools.dotc.Driver.process(Driver.scala:181)
at dotty.tools.dotc.Driver.main(Driver.scala:211)
at dotty.tools.MainGenericCompiler$.run$1(MainGenericCompiler.scala:162)
at dotty.tools.MainGenericCompiler$.main(MainGenericCompiler.scala:186)
at dotty.tools.MainGenericCompiler.main(MainGenericCompiler.scala)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at coursier.bootstrap.launcher.a.a(Unknown Source)
at coursier.bootstrap.launcher.Launcher.main(Unknown Source)
Metadata
Metadata
Assignees
Labels
itype:bugitype:crashstat:needs triageEvery issue needs to have an "area" and "itype" labelEvery issue needs to have an "area" and "itype" label