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

Some in a macro reflect-based unapply method can crash the compiler #19362

Open
jchyb opened this issue Jan 3, 2024 · 0 comments
Open

Some in a macro reflect-based unapply method can crash the compiler #19362

jchyb opened this issue Jan 3, 2024 · 0 comments
Assignees
Labels

Comments

@jchyb
Copy link
Contributor

jchyb commented Jan 3, 2024

Compiler version

3.3.1, 3.4.0-RC1-bin-20231223-938d405-NIGHTLY (and presumably other)

Minimized code

UnapplyErrorMain.scala

@main def main() =
  val Unapplier(result) = Some(5)

UnapplyErrorMacro.scala

import scala.quoted._

object Unapplier:
  inline def unapplySeq(arg: Any): Option[Seq[Any]] = ${unapplyImpl('arg)}

  def unapplyImpl(using Quotes)(argExpr: Expr[Any]): Expr[Option[Seq[Any]]] =
    import quotes.reflect._
    Match(
      '{Option.empty[Int]}.asTerm,
      List(
        CaseDef(Unapply(TypeApply(Select.unique(Ref(Symbol.classSymbol("scala.Some").companionModule), "unapply"), List(TypeTree.of[Int])), Nil, List('{5}.asTerm)), None, '{Some(Seq(0))}.asTerm),
        CaseDef(Wildcard(), None, '{Some(Seq(0))}.asTerm)
      )
    ).asExprOf[Option[Seq[Any]]]

Output (click arrow to expand)

  exception while retyping x1.value of class Select # -1

  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/jchyb/Documents/workspace/dotty/UnapplyErrorMain.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.4.0-RC1-bin-20231223-938d405-NIGHTLY-git-938d405
            settings: -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.4.0-RC1-bin-20231223-938d405-NIGHTLY/scala3-library_3-3.4.0-RC1-bin-20231223-938d405-NIGHTLY.jar:/Users/jchyb/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/jchyb/Documents/workspace/dotty/.scala-build/dotty_3200b05eac-8d90288d6d/classes/main -java-output-version 17 -sourceroot /Users/jchyb/Documents/workspace/dotty


  Exception while compiling /Users/jchyb/Documents/workspace/dotty/UnapplyErrorMacro.scala, /Users/jchyb/Documents/workspace/dotty/UnapplyErrorMain.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: <no file>
        during phase: parser
                mode: Mode()
     library version: version 2.13.12
    compiler version: version 3.4.0-RC1-bin-20231223-938d405-NIGHTLY-git-938d405
            settings: -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.4.0-RC1-bin-20231223-938d405-NIGHTLY/scala3-library_3-3.4.0-RC1-bin-20231223-938d405-NIGHTLY.jar:/Users/jchyb/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/jchyb/Documents/workspace/dotty/.scala-build/dotty_3200b05eac-8d90288d6d/classes/main -java-output-version 17 -sourceroot /Users/jchyb/Documents/workspace/dotty

Exception in thread "main" java.lang.AssertionError: assertion failed: no owner from  <none>/ <none> in x1.value
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:717)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3129)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.transform.Erasure$Typer.$anonfun$7(Erasure.scala:855)
        at dotty.tools.dotc.core.Decorators$.zipWithConserve(Decorators.scala:160)
        at dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:855)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3160)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.transform.Erasure$Typer.$anonfun$7(Erasure.scala:855)
        at dotty.tools.dotc.core.Decorators$.zipWithConserve(Decorators.scala:160)
        at dotty.tools.dotc.transform.Erasure$Typer.typedApply(Erasure.scala:855)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3160)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedIf(Typer.scala:1267)
        at dotty.tools.dotc.transform.Erasure$Typer.typedIf(Erasure.scala:888)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3169)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3374)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1193)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1197)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3168)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedLabeled(Typer.scala:1991)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3153)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3318)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.transform.Erasure$Typer.typedTyped(Erasure.scala:632)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3165)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3318)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:903)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3183)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:2539)
        at dotty.tools.dotc.transform.Erasure$Typer.typedValDef(Erasure.scala:912)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3133)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3347)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1193)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1197)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3168)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.$anonfun$14(Typer.scala:1294)
        at dotty.tools.dotc.typer.Applications.harmonic(Applications.scala:2364)
        at dotty.tools.dotc.typer.Applications.harmonic$(Applications.scala:350)
        at dotty.tools.dotc.typer.Typer.harmonic(Typer.scala:121)
        at dotty.tools.dotc.typer.Typer.typedIf(Typer.scala:1297)
        at dotty.tools.dotc.transform.Erasure$Typer.typedIf(Erasure.scala:888)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3169)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3374)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1193)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1197)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3168)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedLabeled(Typer.scala:1991)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3153)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:2539)
        at dotty.tools.dotc.transform.Erasure$Typer.typedValDef(Erasure.scala:912)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3133)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3347)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1193)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1197)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3168)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.typer.Typer.$anonfun$62(Typer.scala:2602)
        at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
        at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2602)
        at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:959)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3136)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3347)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2789)
        at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1047)
        at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3148)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3152)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3243)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3347)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3393)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1058)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2922)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3194)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3244)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3321)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3325)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3437)
        at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:143)
        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:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:357)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:267)
        at dotty.tools.dotc.Driver.finish(Driver.scala:58)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
        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)

Notes:

  • Writing reflect-based UnApply calls works for other classes and objects. It's just Some that is causing the issues.
  • macro call has to be a part of the extractor for this to trigger
  • -Xcheck-macros gives no additional hints
  • When using Some in a quoted expression it compiles (and when converting that Expr to a Term and back), but we cannot match the representation of that Term exactly, as we cannot insert Unapply into Typed (as Typed requires a Term, and Unapply isn't that)
@jchyb jchyb added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label area:erasure area:metaprogramming:reflection Issues related to the quotes reflection API and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 3, 2024
@jchyb jchyb changed the title Some() in a macro reflect-based unapply method can crash the compiler Some in a macro reflect-based unapply method can crash the compiler Jan 3, 2024
@jchyb jchyb self-assigned this Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant