Fix task macro's handling of Symbol owners in <qual>.value

The qualifier of the `.value` call may contain `DefTree`s (e.g.
vals, defs) or `Function` trees. When we snip them out of the
tree and graft them into a new context, we must also call
`changeOwner`, so that the symbol owner structure and the tree
structure are coherent.

Failure to do so resulted in a crash in the compiler backend.

Fixes #1150
This commit is contained in:
Jason Zaugg 2014-03-07 17:48:31 +01:00
parent b02248a560
commit 563415aa6a
2 changed files with 25 additions and 10 deletions

View File

@ -15,3 +15,15 @@ demo := {
val (n, s) = parser.parsed val (n, s) = parser.parsed
s * n s * n
} }
// Tests for correct Symbol owner structure in the lifted qualifiers of
// the `.value` macro within a task macro. (#1150)
val key1 = taskKey[Unit]("")
key1 := {
val foo = (sourceDirectory in Compile).apply(base => base).value.get
testFrameworks.value.flatMap(f =>
None.map(_ => f)
)
()
}

View File

@ -226,17 +226,20 @@ final class ContextUtil[C <: Context](val ctx: C)
object appTransformer extends Transformer object appTransformer extends Transformer
{ {
override def transform(tree: Tree): Tree = override def transform(tree: Tree): Tree =
tree match tree match {
{ case ApplyTree(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) =>
case ApplyTree(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) => subWrapper(nme.decoded, targ.tpe, qual, tree) match { subWrapper(nme.decoded, targ.tpe, qual, tree) match {
case Converted.Success(t, finalTx) => finalTx(t) case Converted.Success(t, finalTx) =>
changeOwner(qual, currentOwner, initialOwner) // Fixes https://github.com/sbt/sbt/issues/1150
finalTx(t)
case Converted.Failure(p,m) => ctx.abort(p, m) case Converted.Failure(p,m) => ctx.abort(p, m)
case _: Converted.NotApplicable[_] => super.transform(tree) case _: Converted.NotApplicable[_] => super.transform(tree)
} }
case _ => super.transform(tree) case _ => super.transform(tree)
} }
} }
appTransformer.atOwner(initialOwner) {
appTransformer.transform(t) appTransformer.transform(t)
} }
}
} }