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. --- .../scala/tools/nsc/transform/TailCalls.scala | 10 +++++- test/files/neg/t1672b.check | 13 +++++++ test/files/neg/t1672b.scala | 41 ++++++++++++++++++++++ test/files/pos/t1672.scala | 10 ++++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/t1672b.check create mode 100644 test/files/neg/t1672b.scala create mode 100644 test/files/pos/t1672.scala diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 95cb052fda..a767850cba 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -327,8 +327,16 @@ abstract class TailCalls extends Transform { transformTrees(cases).asInstanceOf[List[CaseDef]] ) + case Try(block, catches, finalizer @ EmptyTree) => + // SI-1672 Catches are in tail position when there is no finalizer + treeCopy.Try(tree, + noTailTransform(block), + transformTrees(catches).asInstanceOf[List[CaseDef]], + EmptyTree + ) + case Try(block, catches, finalizer) => - // no calls inside a try are in tail position, but keep recursing for nested functions + // no calls inside a try are in tail position if there is a finalizer, but keep recursing for nested functions treeCopy.Try(tree, noTailTransform(block), noTailTransforms(catches).asInstanceOf[List[CaseDef]], 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 { + ??? + } + } +} diff --git a/test/files/pos/t1672.scala b/test/files/pos/t1672.scala new file mode 100644 index 0000000000..5ee6bb1759 --- /dev/null +++ b/test/files/pos/t1672.scala @@ -0,0 +1,10 @@ +object Test { + @annotation.tailrec + def bar : Nothing = { + try { + throw new RuntimeException + } catch { + case _: Throwable => bar + } + } +} -- cgit v1.2.3