Skip to content

Commit 4db37e4

Browse files
committed
Merge pull request scala#1358 from scalamacros/ticket/6392
SI-6392 wraps non-terms before typecheck/eval
2 parents 3b120ff + b8362d6 commit 4db37e4

File tree

5 files changed

+33
-2
lines changed

5 files changed

+33
-2
lines changed

src/compiler/scala/tools/reflect/ToolBoxFactory.scala

+13-2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
6969
}
7070
}
7171

72+
def wrapIntoTerm(tree: Tree): Tree =
73+
if (!tree.isTerm) Block(List(tree), Literal(Constant(()))) else tree
74+
75+
def unwrapFromTerm(tree: Tree): Tree = tree match {
76+
case Block(List(tree), Literal(Constant(()))) => tree
77+
case tree => tree
78+
}
79+
7280
def extractFreeTerms(expr0: Tree, wrapFreeTermRefs: Boolean): (Tree, scala.collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]) = {
7381
val freeTerms = expr0.freeTerms
7482
val freeTermNames = scala.collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]()
@@ -101,7 +109,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
101109
// need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars
102110
var (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = false)
103111
val dummies = freeTerms.map{ case (freeTerm, name) => ValDef(NoMods, name, TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))) }.toList
104-
expr = Block(dummies, expr)
112+
expr = Block(dummies, wrapIntoTerm(expr))
105113

106114
// [Eugene] how can we implement that?
107115
// !!! Why is this is in the empty package? If it's only to make
@@ -136,6 +144,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
136144
}
137145
}.transform(unwrapped)
138146
new TreeTypeSubstituter(dummies1 map (_.symbol), dummies1 map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped)
147+
unwrapped = if (expr0.isTerm) unwrapped else unwrapFromTerm(unwrapped)
139148
unwrapped
140149
}
141150

@@ -169,7 +178,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
169178
}
170179
})
171180

172-
def compile(expr: Tree): () => Any = {
181+
def compile(expr0: Tree): () => Any = {
182+
val expr = wrapIntoTerm(expr0)
183+
173184
val freeTerms = expr.freeTerms // need to calculate them here, because later on they will be erased
174185
val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order
175186
verify(expr)

test/files/run/t6392a.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
()

test/files/run/t6392a.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.reflect.runtime.universe._
2+
import scala.reflect.runtime.{currentMirror => cm}
3+
import scala.tools.reflect.ToolBox
4+
5+
object Test extends App {
6+
val tb = cm.mkToolBox()
7+
val c = tb.parse("object C")
8+
println(tb.eval(c))
9+
}

test/files/run/t6392b.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ModuleDef(Modifiers(), newTermName("C"), Template(List(Select(Ident(scala#PK), newTypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(newTypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(())))))))

test/files/run/t6392b.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.reflect.runtime.universe._
2+
import scala.reflect.runtime.{currentMirror => cm}
3+
import scala.tools.reflect.ToolBox
4+
5+
object Test extends App {
6+
val tb = cm.mkToolBox()
7+
val c = tb.parse("object C")
8+
println(showRaw(tb.typeCheck(c), printKinds = true))
9+
}

0 commit comments

Comments
 (0)