From 79e937bea265675c73bca753ba74dc1a829b8737 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 11 Mar 2012 10:50:57 -0400 Subject: Fix for tailcall transform/recognition bugs. Closes SI-3275, SI-5455. --- .../scala/tools/nsc/transform/TailCalls.scala | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 848d6be47b..fdb5c7e52e 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -223,8 +223,25 @@ abstract class TailCalls extends Transform { } tree match { - case dd @ DefDef(_, _, _, vparamss0, _, rhs0) => + case ValDef(_, _, _, _) => + if (tree.symbol.isLazy && tree.symbol.hasAnnotation(TailrecClass)) + unit.error(tree.pos, "lazy vals are not tailcall transformed") + + super.transform(tree) + + case dd @ DefDef(_, _, _, vparamss0, _, rhs0) if !dd.symbol.hasAccessorFlag => val newCtx = new Context(dd) + def isRecursiveCall(t: Tree) = { + val sym = t.symbol + (sym != null) && { + sym.isMethod && (dd.symbol.name == sym.name) && (dd.symbol.enclClass isSubClass sym.enclClass) + } + } + if (newCtx.isMandatory) { + if (!rhs0.exists(isRecursiveCall)) { + unit.error(tree.pos, "@tailrec annotated method contains no recursive calls") + } + } debuglog("Considering " + dd.name + " for tailcalls") val newRHS = transform(rhs0, newCtx) @@ -248,7 +265,7 @@ abstract class TailCalls extends Transform { )) } else { - if (newCtx.isMandatory) + if (newCtx.isMandatory && newRHS.exists(isRecursiveCall)) newCtx.tailrecFailure() newRHS -- cgit v1.2.3