-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIarea:private optionsIssues tied to -Y private/internal compiler settings.Issues tied to -Y private/internal compiler settings.itype:bugitype:crashstat:changed in nextIssues for which the behaviour is different in Scala Next, but the issue remains valid there.Issues for which the behaviour is different in Scala Next, but the issue remains valid there.
Milestone
Description
Compiler version
3.3.1-RC1-bin-20230216-2507577-NIGHTLY
Minimized code
Consider the following macro definition (the macro annotation extracts the number v
that is applied to locally
in inlineMethod
):
import scala.annotation.MacroAnnotation
import scala.quoted.*
class annotation extends MacroAnnotation:
def transform(using Quotes)(tree: quotes.reflect.Definition) =
import quotes.reflect.*
tree match
case tree: ClassDef =>
val List(DefDef(name, paramss, tpt, Some(body))) = tree.body: @unchecked
val rhs = body match
case Inlined(_, _, Block(List(Apply(_ /* `locally` */, List(rhs))), _)) => rhs
val method = DefDef.copy(tree.body.head)(name, paramss, tpt, Some(rhs.changeOwner(tree.body.head.symbol)))
List(ClassDef.copy(tree)(tree.name, tree.constructor, tree.parents, tree.self, List(method)))
Macro call site:
transparent inline def inlineMethod(v: Int) =
locally(v)
0
@annotation
class Test:
def method = inlineMethod(42)
Output
When compiling with -Ycheck:all
, the compiler crashes; otherwise, the code compiles. It seems that the transparent inline
method is crucial to produce the crash.
Error and Stack Trace
*** error while checking Test.scala after phase inlining ***
java.util.NoSuchElementException: head of empty list while running Ycheck on Test.scala
java.util.NoSuchElementException: head of empty list while compiling Test.scala, TestMacro.scala
[error] ## Exception when compiling 2 sources
[error] java.util.NoSuchElementException: head of empty list
[error] scala.collection.immutable.Nil$.head(List.scala:662)
[error] scala.collection.immutable.Nil$.head(List.scala:661)
[error] dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:45)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1620)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1661)
[error] dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:53)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.fold$1(Trees.scala:1532)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.apply(Trees.scala:1534)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1627)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1661)
[error] dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:53)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1624)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1661)
[error] dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:53)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1660)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.fold$1(Trees.scala:1532)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.apply(Trees.scala:1534)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1633)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1661)
[error] dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:53)
[error] dotty.tools.dotc.transform.YCheckPositions.checkPostCondition(YCheckPositions.scala:58)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted$$anonfun$1(TreeChecker.scala:412)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:412)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3077)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3081)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:378)
[error] dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3193)
[error] dotty.tools.dotc.transform.TreeChecker.check(TreeChecker.scala:126)
[error] dotty.tools.dotc.transform.TreeChecker.run(TreeChecker.scala:106)
[error] dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:324)
[error] scala.collection.immutable.List.map(List.scala:246)
[error] dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:328)
[error] dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:247)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
[error] dotty.tools.dotc.Run.runPhases$1(Run.scala:263)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:271)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:280)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:280)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:201)
[error] dotty.tools.dotc.Driver.finish(Driver.scala:56)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:36)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
Note that I'm not entirely certain whether extracting a subtree of an Inlined
node using Inlined(_, _, Block(List(Apply(_, List(rhs))), _))
is legal, but I think it should be (how else would you get the tree to process it further).
Metadata
Metadata
Assignees
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIarea:private optionsIssues tied to -Y private/internal compiler settings.Issues tied to -Y private/internal compiler settings.itype:bugitype:crashstat:changed in nextIssues for which the behaviour is different in Scala Next, but the issue remains valid there.Issues for which the behaviour is different in Scala Next, but the issue remains valid there.