summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2008-06-04 12:55:06 +0000
committerIulian Dragos <jaguarul@gmail.com>2008-06-04 12:55:06 +0000
commita5ef3d597df276500e294d5f758ce7d7033e8835 (patch)
treee5e1b4f868c939d03eef7db9b2663009271bb96e /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parentfb88e0421c9ae85c795b1913f0165ffab5b092f3 (diff)
downloadscala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.gz
scala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.bz2
scala-a5ef3d597df276500e294d5f758ce7d7033e8835.zip
Fixed #981.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 216029b64f..582baba778 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -146,6 +146,11 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
private val byNameArgs = new HashSet[Tree]
private val noApply = new HashSet[Tree]
+ override def transformUnit(unit: CompilationUnit) {
+ freeMutableVars.clear
+ freeLocalsTraverser(unit.body)
+ unit.body = transform(unit.body)
+ }
override def transform(tree: Tree): Tree = try { //debug
postTransform(mainTransform(tree))
} catch {
@@ -464,9 +469,14 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
}
- case ValDef(_, _, _, rhs)
- if (!tree.symbol.owner.isSourceMethod) =>
+ case ValDef(_, _, _, rhs) =>
+ val sym = tree.symbol
+ // a local variable that is mutable and free somewhere later should be lifted
+ // as lambda lifting (coming later) will wrap 'rhs' in an Ref object.
+ if (!sym.owner.isSourceMethod || (sym.isVariable && freeMutableVars(sym)))
withNeedLift(true) { super.transform(tree) }
+ else
+ super.transform(tree)
/*
case Apply(Select(Block(List(), Function(vparams, body)), nme.apply), args) =>
// perform beta-reduction; this helps keep view applications small
@@ -617,4 +627,25 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
}
}
+
+ import collection.mutable
+ /** Set of mutable local variables that are free in some inner method. */
+ private val freeMutableVars: mutable.Set[Symbol] = new mutable.HashSet
+
+ private val freeLocalsTraverser = new Traverser {
+ var currentMethod: Symbol = NoSymbol
+ override def traverse(tree: Tree) = tree match {
+ case DefDef(_, _, _, _, _, _) =>
+ val lastMethod = currentMethod
+ currentMethod = tree.symbol
+ super.traverse(tree)
+ currentMethod = lastMethod
+ case Ident(_) =>
+ val sym = tree.symbol
+ if (sym.isVariable && sym.owner.isMethod && sym.owner != currentMethod)
+ freeMutableVars += sym
+ case _ =>
+ super.traverse(tree)
+ }
+ }
}