aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/TailRec.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-09-12 01:21:10 +0200
committerMartin Odersky <odersky@gmail.com>2014-09-12 02:23:47 +0200
commit97828b370d9b5e0a4c5b4ec5b1da1c174e417df9 (patch)
tree4253640c96974c98cd615b9a34be91f26d69dceb /src/dotty/tools/dotc/transform/TailRec.scala
parent7af0b4bd179a40b75992487dfda2c9f84af852db (diff)
downloaddotty-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.scala40
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)