scala3
scala3 copied to clipboard
summonAll after importing givens from a function parameter causes compiler crash
Compiler version
3.4.0-RC2
Minimized code
import compiletime.summonAll
import deriving.Mirror
type Sc[X] = X
case class Row[T[_]](name: T[String])
class DialectTypeMappers:
given String = ???
inline def metadata(dialect: DialectTypeMappers)(using m: Mirror.Of[Row[Sc]]): m.MirroredElemTypes =
import dialect.given
summonAll[m.MirroredElemTypes]
def f = metadata(???)
Output (click arrow to expand)
unhandled exception while running MegaPhase{lambdaLift, elimStaticThis, countOuterAccesses} on /Users/martin/development/macro-test/main.scala
An unhandled exception was thrown in the compiler.
Please file a crash report here:
https://github.com/lampepfl/dotty/issues/new/choose
For non-enriched exceptions, compile with -Yno-enrich-error-messages.
while compiling: /Users/martin/development/macro-test/main.scala
during phase: MegaPhase{lambdaLift, elimStaticThis, countOuterAccesses}
mode: Mode(ImplicitsEnabled)
library version: version 2.13.12
compiler version: version 3.4.0-RC2
settings: -classpath /Users/martin/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.4.0-RC2/scala3-library_3-3.4.0-RC2.jar:/Users/martin/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.12/scala-library-2.13.12.jar -d /Users/martin/development/macro-test/.scala-build/macro-test_3200b05eac-d141fe35e1/classes/main -java-output-version 17 -sourceroot /Users/martin/development/macro-test
Exception in thread "main" java.lang.IllegalArgumentException: Could not find proxy for dialect: DialectTypeMappers in [parameter dialect, method metadata, the top-level definitions in package <empty>, package <empty>, package <root>], encl = method f, owners = method f, the top-level definitions in package <empty>, package <empty>, package <root>; enclosures = method f, the top-level definitions in package <empty>, package <empty>, package <root>
at dotty.tools.dotc.transform.LambdaLift$Lifter.searchIn$1(LambdaLift.scala:137)
at dotty.tools.dotc.transform.LambdaLift$Lifter.proxy(LambdaLift.scala:150)
at dotty.tools.dotc.transform.LambdaLift$Lifter.proxyRef(LambdaLift.scala:168)
at dotty.tools.dotc.transform.LambdaLift.transformIdent(LambdaLift.scala:287)
at dotty.tools.dotc.transform.MegaPhase.goIdent(MegaPhase.scala:617)
at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:236)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:448)
at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:240)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:448)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:291)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.loop$3(MegaPhase.scala:482)
at dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:482)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:292)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:333)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.loop$2$$anonfun$1(MegaPhase.scala:470)
at dotty.tools.dotc.transform.MegaPhase.loop$2(MegaPhase.scala:472)
at dotty.tools.dotc.transform.MegaPhase.transformBlock(MegaPhase.scala:472)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:311)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:333)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.loop$2$$anonfun$1(MegaPhase.scala:470)
at dotty.tools.dotc.transform.MegaPhase.loop$2(MegaPhase.scala:472)
at dotty.tools.dotc.transform.MegaPhase.transformBlock(MegaPhase.scala:472)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:311)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:261)
at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:264)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:448)
at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:461)
at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:461)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:372)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:268)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:448)
at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:461)
at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:461)
at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:392)
at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:395)
at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:450)
at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:477)
at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:489)
at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:354)
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:333)
at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:360)
at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:315)
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:337)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:348)
at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:357)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:71)
at dotty.tools.dotc.Run.compileUnits(Run.scala:357)
at dotty.tools.dotc.Run.compileSources(Run.scala:261)
at dotty.tools.dotc.Run.compile(Run.scala:246)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
at dotty.tools.dotc.Driver.process(Driver.scala:197)
at dotty.tools.dotc.Driver.process(Driver.scala:165)
at dotty.tools.dotc.Driver.process(Driver.scala:177)
at dotty.tools.dotc.Driver.main(Driver.scala:207)
at dotty.tools.dotc.Main.main(Main.scala)
Compilation failed
note: could be related to https://github.com/lampepfl/dotty/issues/19436
Miminized
import compiletime.{summonInline, summonAll}
class DialectTypeMappers:
given aString: String = ???
inline def metadata(dialect: DialectTypeMappers): Unit =
import dialect.given
summonInline[String]
// summonAll[Tuple1[String]]
def f =
metadata((??? : DialectTypeMappers))
scalac -Xprint:inlining shows
def f: Unit =
{
val dialect$proxy1: DialectTypeMappers = ??? :DialectTypeMappers
{
import dialect$proxy1.given
{
dialect.aString
()
}
}:Unit
}
where dialect.aString should have been dialect$proxy1.aString
summon works correctly, therefore I assume that the context is properly updated with the correct import before expanding summonInline.
My best guess so far we are using the wrong context here https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/inlines/Inlines.scala#L427-L437
This issue was picked for the Issue Spree of Februrary 27th, 2024. @natsukagami, @KuceraMartin and @jan-pieter will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here.
Some more context:
Looking at InlinerMap, it seems that Import trees have their qualifiers renamed, but the underlying denotation is not changed. This is later used by Typer to infer the imported givens into the context (through importContext). That's how the dialect got through.
@EugeneFlesselle, do you plan to work on this?