diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2008-06-04 12:55:06 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2008-06-04 12:55:06 +0000 |
commit | a5ef3d597df276500e294d5f758ce7d7033e8835 (patch) | |
tree | e5e1b4f868c939d03eef7db9b2663009271bb96e | |
parent | fb88e0421c9ae85c795b1913f0165ffab5b092f3 (diff) | |
download | scala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.gz scala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.bz2 scala-a5ef3d597df276500e294d5f758ce7d7033e8835.zip |
Fixed #981.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 35 | ||||
-rw-r--r-- | test/files/run/try.scala | 19 |
2 files changed, 52 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) + } + } } diff --git a/test/files/run/try.scala b/test/files/run/try.scala index 934ebaa2e7..594c630cc8 100644 --- a/test/files/run/try.scala +++ b/test/files/run/try.scala @@ -85,6 +85,24 @@ object Test extends AnyRef with Application { Console.println(result); } + // ticket #981 + def try6 { + class SekwencjaArray { + def get = null + } + + var sekw : SekwencjaArray = + try { + null + } catch { + case _ => null + } + + new AnyRef { + def getValueAt(row:Int, col:Int) = sekw.get + } + } + /* def finally1 = { Console.print("1 + 1 = "); @@ -104,6 +122,7 @@ object Test extends AnyRef with Application { try3; try4; try5; + try6; Console.println; new A(); () |