From 264e49a912a9c92b5c5f91c51bbf14d27f9d3757 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 28 Jan 2014 10:45:15 +0100 Subject: [PATCH] Avoid compiler crash for naked `key.value` calls. Untyped trees underneath typed trees makes Jack and sad boy. And they make superaccessors a sad phase. The recent refactoring to retain original types in the trees representing the argument to the task macro meant that the `value` macro also was changed to try to avoid this untyped-under-typed problem. However, it didn't go deep enough, and left the child trees of the placeholder tree `InputWrapper.wrap[T](key)` untyped. This commit uses `c.typeCheck` to locally typeheck that tree fully instead. Fixes #1031 --- .../src/main/scala/sbt/std/InputWrapper.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main/settings/src/main/scala/sbt/std/InputWrapper.scala b/main/settings/src/main/scala/sbt/std/InputWrapper.scala index 400dbc8f8..5a2ee0dd1 100644 --- a/main/settings/src/main/scala/sbt/std/InputWrapper.scala +++ b/main/settings/src/main/scala/sbt/std/InputWrapper.scala @@ -75,8 +75,16 @@ object InputWrapper sel.setPos(pos) // need to set the position on Select, because that is where the compileTimeOnly check looks val tree = ApplyTree(TypeApply(sel, TypeTree(tpe) :: Nil), ts.tree :: Nil) tree.setPos(ts.tree.pos) - tree.setType(tpe) - c.Expr[T](tree) + // JZ: I'm not sure why we need to do this. Presumably a caller is wrapping this tree in a + // typed tree *before* handing the whole thing back to the macro engine. One must never splice + // untyped trees under typed trees, as the type checker doesn't descend if `tree.tpe == null`. + // + // #1031 The previous attempt to fix this just set the type on `tree`, which worked in cases when the + // call to `.value` was inside a the task macro and eliminated before the end of the typer phase. + // But, if a "naked" call to `.value` left the typer, the superaccessors phase would freak out when + // if hit the untyped trees, before we could get to refchecks and the desired @compileTimeOnly warning. + val typedTree = c.typeCheck(tree) + c.Expr[T](typedTree) } def valueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] =