From 31a0aa75cf9739b2ae565d634670f6c0ce89bbc1 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 5 Dec 2012 14:16:27 +0100 Subject: SI-1672 Catches are in tail position without finally. So we can eliminate tail calls within. --- test/files/neg/t1672b.check | 13 +++++++++++++ test/files/neg/t1672b.scala | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 test/files/neg/t1672b.check create mode 100644 test/files/neg/t1672b.scala (limited to 'test/files/neg') diff --git a/test/files/neg/t1672b.check b/test/files/neg/t1672b.check new file mode 100644 index 0000000000..288e47c315 --- /dev/null +++ b/test/files/neg/t1672b.check @@ -0,0 +1,13 @@ +t1672b.scala:3: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position + def bar : Nothing = { + ^ +t1672b.scala:14: error: could not optimize @tailrec annotated method baz: it contains a recursive call not in tail position + def baz : Nothing = { + ^ +t1672b.scala:29: error: could not optimize @tailrec annotated method boz: it contains a recursive call not in tail position + case _: Throwable => boz; ??? + ^ +t1672b.scala:34: error: could not optimize @tailrec annotated method bez: it contains a recursive call not in tail position + def bez : Nothing = { + ^ +four errors found diff --git a/test/files/neg/t1672b.scala b/test/files/neg/t1672b.scala new file mode 100644 index 0000000000..7d02ddc710 --- /dev/null +++ b/test/files/neg/t1672b.scala @@ -0,0 +1,41 @@ +object Test { + @annotation.tailrec + def bar : Nothing = { + try { + throw new RuntimeException + } catch { + case _: Throwable => bar + } finally { + bar + } + } + + @annotation.tailrec + def baz : Nothing = { + try { + throw new RuntimeException + } catch { + case _: Throwable => baz + } finally { + ??? + } + } + + @annotation.tailrec + def boz : Nothing = { + try { + throw new RuntimeException + } catch { + case _: Throwable => boz; ??? + } + } + + @annotation.tailrec + def bez : Nothing = { + try { + bez + } finally { + ??? + } + } +} -- cgit v1.2.3 From 8434922d6f0ead95a2109a5e41f4db4136449e93 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 5 Dec 2012 16:44:53 +0100 Subject: Addtional test cases for tail calls in catches. - Includes a run test to check bytecode verifies and behaves - Show this isn't possible when try is used as an expression, and a `liftedTree` local method is needed. --- test/files/neg/t1672b.check | 5 ++++- test/files/neg/t1672b.scala | 11 +++++++++++ test/files/run/t1672.scala | 28 ++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t1672.scala (limited to 'test/files/neg') diff --git a/test/files/neg/t1672b.check b/test/files/neg/t1672b.check index 288e47c315..60ccf77174 100644 --- a/test/files/neg/t1672b.check +++ b/test/files/neg/t1672b.check @@ -10,4 +10,7 @@ t1672b.scala:29: error: could not optimize @tailrec annotated method boz: it con t1672b.scala:34: error: could not optimize @tailrec annotated method bez: it contains a recursive call not in tail position def bez : Nothing = { ^ -four errors found +t1672b.scala:46: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position + else 1 + (try { + ^ +5 errors found diff --git a/test/files/neg/t1672b.scala b/test/files/neg/t1672b.scala index 7d02ddc710..0ccdd03633 100644 --- a/test/files/neg/t1672b.scala +++ b/test/files/neg/t1672b.scala @@ -38,4 +38,15 @@ object Test { ??? } } + + // the `liftedTree` local method will prevent a tail call here. + @annotation.tailrec + def bar(i : Int) : Int = { + if (i == 0) 0 + else 1 + (try { + throw new RuntimeException + } catch { + case _: Throwable => bar(i - 1) + }) + } } diff --git a/test/files/run/t1672.scala b/test/files/run/t1672.scala new file mode 100644 index 0000000000..ee025b9031 --- /dev/null +++ b/test/files/run/t1672.scala @@ -0,0 +1,28 @@ +object Test { + @annotation.tailrec + def bar(i : Int) : Int = { + if (i == 0) 0 + else try { + throw new RuntimeException + } catch { + case _: Throwable => bar(i - 1) + } + } + + @annotation.tailrec + def nestedTry1(i : Int) : Int = { + if (i == 0) 0 + else try { + throw new RuntimeException + } catch { + case _: Throwable => + try { ??? } catch { case _: Throwable => nestedTry1(i - 1) } + } + } + + def main(args: Array[String]) { + assert(bar(2) == 0) + + assert(nestedTry1(2) == 0) + } +} -- cgit v1.2.3