Skip to content

inserting EmptyTree when recovering from StopMacroException can lead to AssertionError instead of user message #14039

Closed
@scf37

Description

@scf37

From what I can see in debugger, macro throws StopMacroException, then Splicer catches it and inserts EmptyTree at Splicer.scala:70. But resulting AST is incorrect and leads to further AssertionError without emitting user error.

Compiler version

3.1.0

Minimized code

  inline def apply[A, Request, Response](method: String, uri: String, handler: A, methodName: String, modifiers: Seq[RouteModifier]): Endpoint[Request, Response] =
    ${Macro.impl[A, Request, Response]('method, 'uri, 'handler, 'methodName, 'modifiers)}

  def impl[A: Type, Request: Type, Response: Type](methodExpr: Expr[String], uriExpr: Expr[String], handlerExpr: Expr[A], methodNameExpr: Expr[String], modifiersExpr: Expr[Seq[RouteModifier]])(using Quotes): Expr[Endpoint[Request, Response]] = {
    import quotes.reflect.*
   report.errorAndAbort("my message")
  }

// macro invocation code
trait Dsl[Request, Response] {
  val entries = Seq.newBuilder[Endpoint[Request, Response]]

  protected inline def get[A](inline uri: String, handler: A, methodName: String, modifiers: RouteModifier*): Unit = entries += Macro[A, Request, Response]("get", uri, handler, methodName, modifiers)
  protected inline def post[A](inline uri: String, handler: A, methodName: String, modifiers: RouteModifier*): Unit = entries += Macro[A, Request, Response]("post", uri, handler, methodName, modifiers)
}

Output (click arrow to expand)

Exception in thread "main" java.lang.AssertionError: assertion failed: Select(TypedSplice(Select(Inlined(EmptyTree,List(),Ident(Dsl_this)),entries)),+)
	at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedSelect(Inliner.scala:1503)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2725)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2817)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3003)
	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:885)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1035)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:317)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedApply(Inliner.scala:1547)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2755)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2818)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.Typer.reassignmentToVal$1(Typer.scala:954)
	at dotty.tools.dotc.typer.Typer.typedAssign(Typer.scala:1015)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2762)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2818)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.Applications.typedOpAssign$1(Applications.scala:1017)
	at dotty.tools.dotc.typer.Applications.$anonfun$22$$anonfun$1(Applications.scala:1026)
	at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:3011)
	at dotty.tools.dotc.typer.Applications.$anonfun$5(Applications.scala:1030)
	at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:3014)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1031)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:317)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedApply(Inliner.scala:1547)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2755)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2818)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2936)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2959)
	at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1027)
	at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1031)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2763)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2818)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:62)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2760)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2818)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:121)
	at dotty.tools.dotc.typer.Inliner$InlineTyper.typedUnadapted(Inliner.scala:1634)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2883)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2880)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2887)
	at dotty.tools.dotc.typer.Inliner.inlined(Inliner.scala:1019)
	at dotty.tools.dotc.typer.Inliner$.inlineCall(Inliner.scala:155)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:85)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.traverse$1(TreeMapWithImplicits.scala:53)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transformStats(TreeMapWithImplicits.scala:60)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:111)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:79)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1473)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:120)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:79)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.traverse$1(TreeMapWithImplicits.scala:53)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transformStats(TreeMapWithImplicits.scala:60)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:111)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:79)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1473)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:120)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:79)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.traverse$1(TreeMapWithImplicits.scala:53)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transformStats(TreeMapWithImplicits.scala:60)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1484)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:120)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:93)
	at dotty.tools.dotc.transform.Inlining$$anon$2.transform(Inlining.scala:71)
	at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:21)
	at dotty.tools.dotc.transform.Inlining.run(Inlining.scala:43)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:308)
	at scala.collection.immutable.List.map(List.scala:246)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:309)
	at dotty.tools.dotc.transform.Inlining.runOn(Inlining.scala:47)
	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:261)
	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$5(Run.scala:272)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:280)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:289)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:228)
	at dotty.tools.repl.ReplCompiler.runCompilationUnit(ReplCompiler.scala:155)
	at dotty.tools.repl.ReplCompiler.compile(ReplCompiler.scala:165)
	at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:250)
	at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:218)
	at dotty.tools.repl.ReplDriver.run$$anonfun$1(ReplDriver.scala:161)
	at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:174)
	at dotty.tools.repl.ReplDriver.run(ReplDriver.scala:162)
	at dotty.tools.repl.ScriptEngine.eval(ScriptEngine.scala:38)
	at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at Main$package$.main(Main.scala:51)
	at main.main(Main.scala:44)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions