Skip to content

Regression in macro expansion: compiler crashes #6171

@liufengyun

Description

@liufengyun

The following code crashes the compiler:

// assert_1.scala
import scala.quoted._
import scala.tasty._

object scalatest {

  inline def assert(condition: => Boolean): Unit = ${ assertImpl('condition, '{""}) }

  def assertImpl(cond: Expr[Boolean], clue: Expr[Any])(implicit refl: Reflection): Expr[Unit] = {
    import refl._
    import util._
    import quoted.Toolbox.Default._

    def isImplicitMethodType(tp: Type): Boolean =
      Type.IsMethodType.unapply(tp).flatMap(tp => if tp.isImplicit then Some(true) else None).nonEmpty

    cond.unseal.underlyingArgument match {
      case t @ Term.Apply(Term.Select(lhs, op), rhs :: Nil) =>
        let(lhs) { left =>
          let(rhs) { right =>
            val app = Term.Select.overloaded(left, op, Nil, right :: Nil)
            let(app) { result =>
              val l = left.seal[Any]
              val r = right.seal[Any]
              val b = result.seal[Boolean]
              val code = '{ scala.Predef.assert($b) }
              code.unseal
            }
          }
        }.seal[Unit]
      case Term.Apply(f @ Term.Apply(Term.Select(Term.Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
      if isImplicitMethodType(f.tpe) =>
        let(lhs) { left =>
          let(rhs) { right =>
            val app = Term.Select.overloaded(Term.Apply(qual, left :: Nil), op, Nil, right :: Nil)
            let(Term.Apply(app, implicits)) { result =>
              val l = left.seal[Any]
              val r = right.seal[Any]
              val b = result.seal[Boolean]
              val code = '{ scala.Predef.assert($b) }
              code.unseal
            }
          }
        }.seal[Unit]
    }
  }
}

// test_2.scala
object Test {
  import scalatest._

  def main(args: Array[String]): Unit = {
    assert(new Some(5).get == 5L)
  }
}

Stacktrace:

show log
9 |    assert(new Some(5).get == 5L)
  |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |    An exception occurred while executing macro expansion
  |    NoDenotation.owner
  |    java.lang.AssertionError: NoDenotation.owner
  |    	at dotty.tools.dotc.core.SymDenotations$NoDenotation$.owner(SymDenotations.scala:2076)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1021)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1219)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1207)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1215)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1213)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1207)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1207)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1213)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1029)
  |    	at dotty.tools.dotc.ast.tpd$MapToUnderlying.transform(tpd.scala:1026)
  |    	at dotty.tools.dotc.ast.tpd$TreeOps$.underlyingArgument$extension(tpd.scala:977)
  |    	at dotty.tools.dotc.tastyreflect.KernelImpl.Term_underlyingArgument(KernelImpl.scala:237)
  |    	at dotty.tools.dotc.tastyreflect.KernelImpl.Term_underlyingArgument(KernelImpl.scala:237)
  |    	at scala.tasty.reflect.TreeOps$TermAPI.underlyingArgument(TreeOps.scala:180)
  |    	at scalatest$.assertImpl(assert_1.scala:16)
  |    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  |    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  |    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  |    	at java.lang.reflect.Method.invoke(Method.java:498)
  |    	at dotty.tools.dotc.transform.Splicer$Interpreter.interpretStaticMethodCall$$anonfun$1(Splicer.scala:128)
  |    	at dotty.tools.dotc.transform.Splicer$Interpreter.stopIfRuntimeException(Splicer.scala:181)
  |    	at dotty.tools.dotc.transform.Splicer$Interpreter.interpretStaticMethodCall(Splicer.scala:128)
  |    	at dotty.tools.dotc.transform.Splicer$AbstractInterpreter.interpretTree(Splicer.scala:336)
  |    	at dotty.tools.dotc.transform.Splicer$Interpreter.interpret(Splicer.scala:83)
  |    	at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:44)
  |    	at dotty.tools.dotc.typer.Inliner.dotty$tools$dotc$typer$Inliner$$expandMacro(Inliner.scala:1161)
  |    	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedApply(Inliner.scala:997)
  |    	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2025)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
  |    	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:110)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:59)
  |    	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2029)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
  |    	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:110)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2111)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Inliner.inlined(Inliner.scala:510)
  |    	at dotty.tools.dotc.typer.Inliner$.inlineCall(Inliner.scala:109)
  |    	at dotty.tools.dotc.typer.Typer.adaptNoArgsOther$4(Typer.scala:2656)
  |    	at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:2731)
  |    	at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:2940)
  |    	at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:2357)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2197)
  |    	at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:702)
  |    	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2032)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2197)
  |    	at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:1551)
  |    	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2012)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2078)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2144)
  |    	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2186)
  |    	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1674)
  |    	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2015)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2078)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2144)
  |    	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2186)
  |    	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:1795)
  |    	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2055)
  |    	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2113)
  |    	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
  |    	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2197)
  |    	at dotty.tools.dotc.typer.FrontEnd.typeCheck$$anonfun$1(FrontEnd.scala:61)
  |    	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
  |    	at dotty.tools.dotc.typer.FrontEnd.monitor(FrontEnd.scala:35)
  |    	at dotty.tools.dotc.typer.FrontEnd.typeCheck(FrontEnd.scala:65)
  |    	at dotty.tools.dotc.typer.FrontEnd.runOn$$anonfun$2(FrontEnd.scala:89)
  |    	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
  |    	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
  |    	at scala.collection.immutable.List.foreach(List.scala:392)
  |    	at dotty.tools.dotc.typer.FrontEnd.runOn(FrontEnd.scala:89)
  |    	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:158)
  |    	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
  |    	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
  |    	at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:36)
  |    	at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:33)
  |    	at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:198)
  |    	at dotty.tools.dotc.Run.runPhases$5(Run.scala:170)
  |    	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:178)
  |    	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
  |    	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:102)
  |    	at dotty.tools.dotc.Run.compileUnits(Run.scala:185)
  |    	at dotty.tools.dotc.Run.compileSources(Run.scala:120)
  |    	at dotty.tools.dotc.Run.compile(Run.scala:104)
  |    	at dotty.tools.dotc.Driver.doCompile(Driver.scala:33)
  |    	at dotty.tools.dotc.Driver.process(Driver.scala:170)
  |    	at dotty.tools.dotc.Driver.process(Driver.scala:139)
  |    	at dotty.tools.vulpix.ParallelTesting$Test.compile(ParallelTesting.scala:378)
  |    	at dotty.tools.vulpix.ParallelTesting$$anon$4.$anonfun$2(ParallelTesting.scala:689)
  |    	at scala.collection.immutable.List.map(List.scala:290)
  |    	at dotty.tools.vulpix.ParallelTesting$$anon$4.checkTestSource$$anonfun$1(ParallelTesting.scala:689)
  |    	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
  |    	at dotty.tools.vulpix.ParallelTesting$Test.tryCompile(ParallelTesting.scala:316)
  |    	at dotty.tools.vulpix.ParallelTesting$$anon$4.checkTestSource(ParallelTesting.scala:715)
  |    	at dotty.tools.vulpix.ParallelTesting$Test$LoggedRunnable.run(ParallelTesting.scala:212)
  |    	at dotty.tools.vulpix.ParallelTesting$$anon$4.run(ParallelTesting.scala:663)
  |    	at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
  |    	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
  |    	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
  |    	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
  |    	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
  |
  | This location is in code that was inlined at test_2.scala:9

Founded in scalatest/scalatest#1559, possibly duplicate of #5715

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions