Never inspect twice the same macro application

In Scala 2.10.4, this macro can produce a stack overflow :

    def foo(a: Any): Any = macro impl
    def impl(c: Context)(a: c.Expr[Any]): c.Expr[Any] = a

Here, an application such as `foo(someVal)` will produce the expansion
`someVal`. As expected, `someVal` has `original` tree `foo(someVal)`,
but if we inspect this tree, we will find that `someVal` has an
original tree, but it shouldn't.

Moreover, in Scala 2.11, some macros have their own application as
`original` trees.

See sbt/sbt#1237 for a description of these problems.

This commit fixes these two problems.

Fixes sbt/sbt#1237
This commit is contained in:
Martin Duhem 2014-06-14 16:58:10 +02:00
parent aef9933d87
commit 26e2449263
2 changed files with 5 additions and 5 deletions

View File

@ -56,12 +56,12 @@ class ExtractUsedNames[GlobalType <: CallbackGlobal](val global: GlobalType) ext
def handleTreeNode(node: Tree): Unit = {
def handleMacroExpansion(original: Tree): Unit = {
// Some macros seem to have themselves registered as original tree.
// In this case, we only need to handle the children of the original tree,
// because we already handled the expanded tree.
// Some macros seem to be their own orignal tree, or appear in the children of their
// original tree. To prevent infinite loops, we need to filter out nodes that we already
// handled.
// This is only relevant for Scala 2.10.4
// See https://issues.scala-lang.org/browse/SI-8486
if (original == node) original.children.foreach(handleTreeNode)
else original.foreach(handleTreeNode)
original.filter(_ ne node).foreach(handleTreeNode)
}
def handleClassicTreeNode(node: Tree): Unit = node match {