summaryrefslogtreecommitdiff
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
parentfb88e0421c9ae85c795b1913f0165ffab5b092f3 (diff)
downloadscala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.gz
scala-a5ef3d597df276500e294d5f758ce7d7033e8835.tar.bz2
scala-a5ef3d597df276500e294d5f758ce7d7033e8835.zip
Fixed #981.
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala35
-rw-r--r--test/files/run/try.scala19
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();
()