diff options
author | Martin Odersky <odersky@gmail.com> | 2014-09-12 01:21:10 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-09-12 02:23:47 +0200 |
commit | 97828b370d9b5e0a4c5b4ec5b1da1c174e417df9 (patch) | |
tree | 4253640c96974c98cd615b9a34be91f26d69dceb /src/dotty/tools/dotc/transform/TailRec.scala | |
parent | 7af0b4bd179a40b75992487dfda2c9f84af852db (diff) | |
download | dotty-97828b370d9b5e0a4c5b4ec5b1da1c174e417df9.tar.gz dotty-97828b370d9b5e0a4c5b4ec5b1da1c174e417df9.tar.bz2 dotty-97828b370d9b5e0a4c5b4ec5b1da1c174e417df9.zip |
Handle return in tailcalls.
Avoids characterizing the "from" link in a return as a tail call
reference.
Diffstat (limited to 'src/dotty/tools/dotc/transform/TailRec.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/TailRec.scala | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala index 83e1e5426..16764de07 100644 --- a/src/dotty/tools/dotc/transform/TailRec.scala +++ b/src/dotty/tools/dotc/transform/TailRec.scala @@ -256,15 +256,29 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete val res: Tree = tree match { + case Ident(qual) => + val sym = tree.symbol + if (sym == method && ctx.tailPos) rewriteApply(tree, sym) + else tree + + case tree: Select => + val sym = tree.symbol + if (sym == method && ctx.tailPos) rewriteApply(tree, sym) + else tpd.cpy.Select(tree)(noTailTransform(tree.qualifier), tree.name) + + case Apply(fun, args) => + val meth = fun.symbol + if (meth == defn.Boolean_|| || meth == defn.Boolean_&&) + tpd.cpy.Apply(tree)(fun, transform(args)) + else + rewriteApply(tree, meth) + case tree@Block(stats, expr) => tpd.cpy.Block(tree)( noTailTransforms(stats), transform(expr) ) - case tree@CaseDef(_, _, body) => - cpy.CaseDef(tree)(body = transform(body)) - case tree@If(cond, thenp, elsep) => tpd.cpy.If(tree)( noTailTransform(cond), @@ -272,6 +286,9 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete transform(elsep) ) + case tree@CaseDef(_, _, body) => + cpy.CaseDef(tree)(body = transform(body)) + case tree@Match(selector, cases) => tpd.cpy.Match(tree)( noTailTransform(selector), @@ -281,29 +298,16 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete case tree: Try => rewriteTry(tree) - case Apply(fun, args) if fun.symbol == defn.Boolean_|| || fun.symbol == defn.Boolean_&& => - tpd.cpy.Apply(tree)(fun, transform(args)) - - case Apply(fun, args) => - rewriteApply(tree, fun.symbol) - case Alternative(_) | Bind(_, _) => assert(false, "We should've never gotten inside a pattern") tree - case tree: Select => - val sym = tree.symbol - if (sym == method && ctx.tailPos) rewriteApply(tree, sym) - else tpd.cpy.Select(tree)(noTailTransform(tree.qualifier), tree.name) - case ValDef(_, _, _, _) | EmptyTree | Super(_, _) | This(_) | Literal(_) | TypeTree(_) | DefDef(_, _, _, _, _, _) | TypeDef(_, _, _) => tree - case Ident(qual) => - val sym = tree.symbol - if (sym == method && ctx.tailPos) rewriteApply(tree, sym) - else tree + case Return(expr, from) => + tpd.cpy.Return(tree)(noTailTransform(expr), from) case _ => super.transform(tree) |