diff options
author | Paul Phillips <paulp@improving.org> | 2012-03-11 10:50:57 -0400 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-03-11 13:23:30 -0400 |
commit | 79e937bea265675c73bca753ba74dc1a829b8737 (patch) | |
tree | 083a4256daec69d3b874afa47939a295ad854188 /src/compiler/scala/tools/nsc/transform/TailCalls.scala | |
parent | f1c39dd9816fd48663064307c39e2d9c8c936cd5 (diff) | |
download | scala-79e937bea265675c73bca753ba74dc1a829b8737.tar.gz scala-79e937bea265675c73bca753ba74dc1a829b8737.tar.bz2 scala-79e937bea265675c73bca753ba74dc1a829b8737.zip |
Fix for tailcall transform/recognition bugs.
Closes SI-3275, SI-5455.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/TailCalls.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/TailCalls.scala | 21 |
1 files changed, 19 insertions, 2 deletions
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 |