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

Enabling -experimental introduces compiler crash in transparent inline macro #21802

Open
WojciechMazur opened this issue Oct 18, 2024 · 2 comments
Assignees
Labels
area:experimental area:metaprogramming:quotes Issues related to quotes and splices area:parser area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore

Comments

@WojciechMazur
Copy link
Contributor

Based on OpenCB failure in 2 projects:

Compiler version

Last good release: 3.5.0-RC1-bin-20240515-177b489-NIGHTLY
First bad release: 3.5.0-RC1-bin-20240516-c608177-NIGHTLY
Bisect points to c8764ba

Minimized code

//> using options -experimental

class ProbeFailedException(cause: Exception) extends Exception(cause)
trait Probing: 
  self: Metrics =>
    val probeFailureCounter: MetricsGroup[Counter] = 
      counters("ustats_probe_failures_count").labelled


trait Counter
class Metrics:
  class counters(name: String):
    transparent inline final def labelled: MetricsGroup[Counter] = MetricsGroup.refine[Counter]
class MetricsGroup[A]
object MetricsGroup:
  import scala.quoted.*
 
  transparent inline final def refine[A]: MetricsGroup[A] =
    ${ refineImpl[A] }

  private def refineImpl[A](using qctx: Quotes, tpe: Type[A]): Expr[MetricsGroup[A]] =
    import qctx.reflect.*

    val mt = MethodType(Nil)(_ => Nil, _ => TypeRepr.of[A])
    val tpe = Refinement(TypeRepr.of[MetricsGroup[A]], "apply", mt).asType
    tpe match
      case '[tpe] =>
        '{ MetricsGroup[A]().asInstanceOf[MetricsGroup[A] & tpe] }

Output

unhandled exception while running posttyper on /Users/wmazur/projects/sandbox/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: /Users/wmazur/projects/sandbox/test.scala
        during phase: posttyper
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.12
    compiler version: version 3.5.0-RC1-bin-SNAPSHOT-git-c8764ba
            settings: -classpath /Users/wmazur/.ivy2/local/org.scala-lang/scala3-library_3/3.5.0-RC1-bin-SNAPSHOT/jars/scala3-library_3.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_265807102e-9acd4df6a7/classes/main -experimental true -java-output-version 17 -sourceroot /Users/wmazur/projects/sandbox


  Exception while compiling /Users/wmazur/projects/sandbox/test.scala, /Users/wmazur/projects/sandbox/test.macros.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: <no file>
        during phase: parser
                mode: Mode()
     library version: version 2.13.12
    compiler version: version 3.5.0-RC1-bin-SNAPSHOT-git-c8764ba
            settings: -classpath /Users/wmazur/.ivy2/local/org.scala-lang/scala3-library_3/3.5.0-RC1-bin-SNAPSHOT/jars/scala3-library_3.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_265807102e-9acd4df6a7/classes/main -experimental true -java-output-version 17 -sourceroot /Users/wmazur/projects/sandbox

Exception in thread "main" dotty.tools.dotc.core.Denotations$StaleSymbolException: stale symbol; module class Metrics$#4138 in module class <empty>, defined in Period(2.1-12), is referred to in run Period(3.9)
        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$Symbol.source(Symbols.scala:321)
        at dotty.tools.dotc.core.Symbols$Symbol.source(Symbols.scala:329)
        at dotty.tools.dotc.typer.Checking$.isNonExperimentalTopLevelDefinition$1(Checking.scala:810)
        at dotty.tools.dotc.typer.Checking$.nonExperimentalTopLevelDefs$1$$anonfun$1(Checking.scala:818)
        at scala.collection.Iterator$$anon$10.nextCur(Iterator.scala:594)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:608)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1300)
        at dotty.tools.dotc.typer.Checking$.markTopLevelDefsAsExperimental$1(Checking.scala:838)
        at dotty.tools.dotc.typer.Checking$.checkAndAdaptExperimentalImports(Checking.scala:846)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:569)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1242)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1613)
        at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:42)
        at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:560)
        at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:20)
        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)

Expectation

Should compile

@Gedochao Gedochao added the regression This worked in a previous version but doesn't anymore label Oct 18, 2024
@Gedochao
Copy link
Contributor

cc @smarter @jchyb

@jchyb jchyb self-assigned this Oct 18, 2024
@smarter
Copy link
Member

smarter commented Oct 18, 2024

#20409 was a stopgap, as noted by Martin in the PR we should really only traverse the symbols of trees we're currently compiling which are therefore guaranteed to not be stale (it seemsisDefinedInCurrentRun is not enough when macros are involved due to the SuspendException mechanism), if we want another stopgap, we can move the isExperimental check earlier, since unlike the sym.source it doesn't force the companion:

diff --git compiler/src/dotty/tools/dotc/typer/Checking.scala compiler/src/dotty/tools/dotc/typer/Checking.scala
index 700bd483ff..eae34c2304 100644
--- compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -807,10 +807,10 @@ object Checking {
     def nonExperimentalTopLevelDefs(pack: Symbol): Iterator[Symbol] =
       def isNonExperimentalTopLevelDefinition(sym: Symbol) =
         sym.isDefinedInCurrentRun
+        && !sym.isExperimental
         && sym.source == ctx.compilationUnit.source
         && !sym.isConstructor // not constructor of package object
         && !sym.is(Package) && !sym.name.isPackageObjectName
-        && !sym.isExperimental

       pack.info.decls.toList.iterator.flatMap: sym =>
         if sym.isClass && (sym.is(Package) || sym.isPackageObject) then

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:experimental area:metaprogramming:quotes Issues related to quotes and splices area:parser area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

No branches or pull requests

4 participants