Skip to content

Compiler crash under combination of value class, lazy vals, macros and derivation #20323

Closed
@WojciechMazur

Description

@WojciechMazur

Found in project recently migrated to Scala 3. We use macros to workaround missing Mirrors for value case classes for Tapir Schemas. Compiler crashes due to stale symbol of OFFSET generated for lazy vals.

Compiler version

All Scala versions

Minimized code

// Needs to be defined in seperate file, away from the references
// model.scala
case class GroupName(value: String) extends AnyVal
object GroupName:
  lazy val foo = "foo"
// derivation.scala
import scala.quoted.*
import scala.deriving.*

trait Schema[T]
object Schema:
  implicit def derivedSchema[T](implicit m: Mirror.Of[T]): Schema[T] = ???

object ValueClassSchemaDerivation:
  inline given [T <: Product & AnyVal]: Schema[T] = ${ valueClassSchema[T] }
  private def valueClassSchema[T <: AnyVal: Type](using Quotes): Expr[Schema[T]] = '{ null.asInstanceOf[Schema[T]] }
// usage.scala
// Unused, but required to reproduce crash
case class ValueClassReferencer(name: GroupName)

@main def Test = 
  import ValueClassSchemaDerivation.given
  summon[Schema[GroupName]]

Output (click arrow to expand)

val OFFSET$_m_0#24499 is invalid at Period(3.78) because decls of module class GroupName$#4133 are List(), do not contain val OFFSET$_m_0
defined =  Period(2.78-86):Long Period(2.87-95):Long

  unhandled exception while running MegaPhase{elimErasedValueType, pureStats, vcElideAllocations, etaReduce, arrayApply, elimPolyFunction, tailrec, completeJavaEnums, mixin, lazyVals, memoize, nonLocalReturns, capturedVars} on /Users/wmazur/projects/sandbox/rocker.repro.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 -Yno-enrich-error-messages.

     while compiling: /Users/wmazur/projects/sandbox/rocker.repro.scala
        during phase: MegaPhase{elimErasedValueType, pureStats, vcElideAllocations, etaReduce, arrayApply, elimPolyFunction, tailrec, completeJavaEnums, mixin, lazyVals, memoize, nonLocalReturns, capturedVars}
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.12
    compiler version: version 3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY-git-e6bc130
            settings: -Ydebug true -classpath /Users/wmazur/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY/scala3-library_3-3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY.jar:/Users/wmazur/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/wmazur/projects/sandbox/.scala-build/sandbox_387e9dc2c9-43f41a03a8/classes/main -java-output-version 17 -sourceroot /Users/wmazur/projects/sandbox


  Exception while compiling /Users/wmazur/projects/sandbox/rocker.macro.scala, /Users/wmazur/projects/sandbox/rocker.model.scala, /Users/wmazur/projects/sandbox/rocker.repro.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 -Yno-enrich-error-messages.

     while compiling: <no file>
        during phase: parser
                mode: Mode()
     library version: version 2.13.12
    compiler version: version 3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY-git-e6bc130
            settings: -Ydebug true -classpath /Users/wmazur/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY/scala3-library_3-3.5.0-RC1-bin-20240501-e6bc130-NIGHTLY.jar:/Users/wmazur/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/wmazur/projects/sandbox/.scala-build/sandbox_387e9dc2c9-43f41a03a8/classes/main -java-output-version 17 -sourceroot /Users/wmazur/projects/sandbox

Exception in thread "main" dotty.tools.dotc.core.Denotations$StaleSymbolException: stale symbol; val OFFSET$_m_0#24499 in module class GroupName$, defined in Period(2.78-86), is referred to in run Period(3.78)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.staleSymbolError(Denotations.scala:961)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:759)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.toNewRun$1(Denotations.scala:806)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:877)
        at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:124)
        at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:118)
        at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:109)
        at dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:546)
        at dotty.tools.dotc.transform.ValueClasses$.valueClassUnbox$$anonfun$1(ValueClasses.scala:28)
        at dotty.tools.dotc.core.Scopes$Scope.filter(Scopes.scala:103)
        at dotty.tools.dotc.core.Scopes$Scope.find(Scopes.scala:113)
        at dotty.tools.dotc.transform.ValueClasses$.valueClassUnbox(ValueClasses.scala:28)
        at dotty.tools.dotc.transform.TreeExtractors$ValueClassUnbox$.unapply(TreeExtractors.scala:44)
        at dotty.tools.dotc.transform.VCElideAllocations.transformApply(VCElideAllocations.scala:45)
        at dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:681)
        at dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:682)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:297)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:327)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.loop$2$$anonfun$1(MegaPhase.scala:474)
        at dotty.tools.dotc.transform.MegaPhase.loop$2(MegaPhase.scala:476)
        at dotty.tools.dotc.transform.MegaPhase.transformBlock(MegaPhase.scala:476)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:315)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.loop$3(MegaPhase.scala:486)
        at dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:486)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:296)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.loop$3(MegaPhase.scala:486)
        at dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:486)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:296)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:265)
        at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:268)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:452)
        at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
        at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:376)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:272)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:452)
        at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
        at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
        at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:396)
        at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:399)
        at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
        at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:481)
        at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:493)
        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:333)
        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.compileUnits(Run.scala:288)
        at dotty.tools.dotc.Run.compileSuspendedUnits(Run.scala:410)
        at dotty.tools.dotc.Driver.finish(Driver.scala:63)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
        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.dotc.Main.main(Main.scala)
Compilation failed

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions