summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/TreeGen.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-07-03 19:23:32 +0000
committerPaul Phillips <paulp@improving.org>2011-07-03 19:23:32 +0000
commit835be39b534accb0d341d0629662f5685ae2cfef (patch)
tree8887c364b1447e4017bbe4395d75de05003202aa /src/compiler/scala/tools/nsc/ast/TreeGen.scala
parent6d3159db055005719cbff30b48a7fbcd659b7240 (diff)
downloadscala-835be39b534accb0d341d0629662f5685ae2cfef.tar.gz
scala-835be39b534accb0d341d0629662f5685ae2cfef.tar.bz2
scala-835be39b534accb0d341d0629662f5685ae2cfef.zip
evalOnce needs to pack the type before using it...
evalOnce needs to pack the type before using it on new valdefs to avoid existential mismatches. Closes #3960, review by moors.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/TreeGen.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index ad9961fc49..d33ca3a6bc 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -174,18 +174,33 @@ abstract class TreeGen extends reflect.internal.TreeGen {
case _ => EmptyTree
}
+ /** Create a ValDef initialized to the given expression, setting the
+ * symbol to its packed type, and an function for creating Idents
+ * which refer to it.
+ */
+ private def mkPackedValDef(expr: Tree, owner: Symbol, name: Name): (ValDef, () => Ident) = {
+ val packedType = typer.packedType(expr, owner)
+ val sym = (
+ owner.newValue(expr.pos.makeTransparent, name)
+ setFlag SYNTHETIC
+ setInfo packedType
+ )
+
+ (ValDef(sym, expr), () => Ident(sym) setPos sym.pos.focus setType expr.tpe)
+ }
+
/** Used in situations where you need to access value of an expression several times
*/
def evalOnce(expr: Tree, owner: Symbol, unit: CompilationUnit)(within: (() => Tree) => Tree): Tree = {
var used = false
if (treeInfo.isPureExpr(expr)) {
within(() => if (used) expr.duplicate else { used = true; expr })
- } else {
- val temp = owner.newValue(expr.pos.makeTransparent, unit.freshTermName("ev$"))
- .setFlag(SYNTHETIC).setInfo(expr.tpe)
- val containing = within(() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
+ }
+ else {
+ val (valDef, identFn) = mkPackedValDef(expr, owner, unit.freshTermName("ev$"))
+ val containing = within(identFn)
ensureNonOverlapping(containing, List(expr))
- Block(List(ValDef(temp, expr)), containing) setPos (containing.pos union expr.pos)
+ Block(List(valDef), containing) setPos (containing.pos union expr.pos)
}
}
@@ -200,11 +215,11 @@ abstract class TreeGen extends reflect.internal.TreeGen {
val idx = i
() => if (used(idx)) expr.duplicate else { used(idx) = true; expr }
}
- } else {
- val temp = owner.newValue(expr.pos.makeTransparent, unit.freshTermName("ev$"))
- .setFlag(SYNTHETIC).setInfo(expr.tpe)
- vdefs += ValDef(temp, expr)
- exprs1 += (() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
+ }
+ else {
+ val (valDef, identFn) = mkPackedValDef(expr, owner, unit.freshTermName("ev$"))
+ vdefs += valDef
+ exprs1 += identFn
}
i += 1
}