Permalink
Browse files

Fix for broken non-local returns.

Don't change the owner of a return if the new owner is nested
inside the old owner.  Closes SI-5612.
  • Loading branch information...
paulp committed May 4, 2012
1 parent f146d58 commit aad6deae7204a7fc95b59ede61b188bb62f51188
@@ -315,11 +315,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
def changeOwner(tree: Tree) = tree match {
case Return(expr) =>
if (tree.symbol == oldowner)
tree.symbol = newowner
if (tree.symbol == oldowner) {
// SI-5612
if (newowner hasTransOwner oldowner)
log("NOT changing owner of %s because %s is nested in %s".format(tree, newowner, oldowner))
else {
log("changing owner of %s: %s => %s".format(tree, oldowner, newowner))
tree.symbol = newowner
}
}
case _: DefTree | _: Function =>
if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner) {
tree.symbol.owner = newowner
}
case _ =>
}
override def traverse(tree: Tree) {
@@ -0,0 +1 @@
Some(1)
@@ -0,0 +1,15 @@
object Test {
def wrap[K](body: => K): K = body
def f(): Option[Int] = {
wrap({ return Some(1) ; None })
}
def main(args: Array[String]) {
println(f())
}
}
// java.lang.ClassCastException: scala.Some cannot be cast to scala.None$
// at Test$$anonfun$f$1.apply(nonlocalreturn.scala:5)
// at Test$$anonfun$f$1.apply(nonlocalreturn.scala:5)
// at Test$.wrap(nonlocalreturn.scala:2)
@@ -0,0 +1,4 @@
START for List(Two, Two, One, Three)
TWO
TWO
ONE
View
@@ -0,0 +1,28 @@
object L extends Enumeration {
val One, Two, Three = Value
}
class Foo {
def foo(xs: List[L.Value]) {
import scala.util.control.Breaks.{break, breakable}
println("START for " + xs)
breakable {
for (x <- xs) {
x match {
case L.One => println("ONE"); return
case L.Two => println("TWO")
case L.Three => println("THREE"); break
}
}
}
println("FINISH")
}
}
object Test {
def main(args: Array[String]) {
val f = new Foo()
val l = List(L.Two, L.Two, L.One, L.Three)
f.foo(l)
}
}

0 comments on commit aad6dea

Please sign in to comment.