From 0b52a5199ba8b949bd80de1eaf589420ef91d6f6 Mon Sep 17 00:00:00 2001 From: James Iry Date: Fri, 18 Jan 2013 16:24:41 -0800 Subject: SI-6863 Fix verify error in captured var inited from expr with try/catch If a captured var was inited from a try/catch we did something reasonable. But if the var was inited from a more complicated expression (if/else, a block, match/case, etc) that ended with a try/catch then we didn't and we were generating faulty byte code. This fix patches LambdaLift to add the missing cases. For known simple expressions, the translation is just new *Ref(expr). For try/catch, if/else, match/case, and blocks this recursively walks down the internal result expressions to translate them. E.g. if(cond) trueExpr else falseExpr becomes if(cone) translate(trueExpr) else translate(falseExpr) For unknown expression types, the translation is {val temp = expr; new *Ref(expr) } --- test/files/run/t6863.scala | 114 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 test/files/run/t6863.scala (limited to 'test/files/run/t6863.scala') diff --git a/test/files/run/t6863.scala b/test/files/run/t6863.scala new file mode 100644 index 0000000000..d77adb6af4 --- /dev/null +++ b/test/files/run/t6863.scala @@ -0,0 +1,114 @@ +/** Make sure that when a variable is captured its initialization expression is handled properly */ +object Test { + def lazyVal() = { + // internally lazy vals become vars which are initialized with "_", so they need to be tested just like vars do + lazy val x = "42" + assert({ () => x }.apply == "42") + } + def ident() = { + val y = "42" + var x = y + assert({ () => x }.apply == "42") + } + def apply() = { + def y(x : Int) = x.toString + var x = y(42) + assert({ () => x }.apply == "42") + } + def literal() = { + var x = "42" + assert({ () => x }.apply == "42") + } + def `new`() = { + var x = new String("42") + assert({ () => x }.apply == "42") + } + def select() = { + object Foo{val bar = "42"} + var x = Foo.bar + assert({ () => x }.apply == "42") + } + def `throw`() = { + var x = if (true) "42" else throw new Exception("42") + assert({ () => x }.apply == "42") + } + def assign() = { + var y = 1 + var x = y = 42 + assert({ () => x}.apply == ()) + } + def valDef() = { + var x = {val y = 42} + assert({ () => x}.apply == ()) + } + def `return`(): String = { + var x = if (true) return "42" else () + assert({ () => x}.apply == ()) + "42" + } + def tryFinally() = { + var x = try { "42" } finally () + assert({ () => x }.apply == "42") + } + def tryCatch() = { + var x = try { "42" } catch { case _ => "43" } + assert({ () => x }.apply == "42") + } + def `if`() = { + var x = if (true) () + assert({ () => x }.apply == ()) + } + def ifElse() = { + var x = if(true) "42" else "43" + assert({ () => x }.apply == "42") + } + def matchCase() = { + var x = 100 match { + case 100 => "42" + case _ => "43" + } + assert({ () => x }.apply == "42") + } + def block() = { + var x = { + val y = 42 + "42" + } + assert({ () => x }.apply == "42") + } + def labelDef() = { + var x = 100 match { + case 100 => try "42" finally () + } + assert({ () => x }.apply == "42") + } + def nested() = { + var x = { + val y = 42 + if(true) try "42" catch {case _ => "43"} + else "44" + } + assert({ () => x }.apply == "42") + } + def main(args: Array[String]) { + lazyVal() + ident() + apply() + literal() + `new`() + select() + `throw`() + assign() + valDef() + `return`() + tryFinally() + tryCatch() + ifElse() + `if`() + matchCase() + block() + labelDef() + nested() + } +} + -- cgit v1.2.3