aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2014-04-14 16:13:11 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-05-06 16:18:45 +0200
commit026b86da4c11a2e4933af00fe65cb2c37851ed3c (patch)
tree5057692a0f42e70a5c1499e02df384b82ba689ad /src
parent9e5cfe27f5d4b34b30102e78222c222ad7604414 (diff)
downloaddotty-026b86da4c11a2e4933af00fe65cb2c37851ed3c.tar.gz
dotty-026b86da4c11a2e4933af00fe65cb2c37851ed3c.tar.bz2
dotty-026b86da4c11a2e4933af00fe65cb2c37851ed3c.zip
Fix TailRec to use Label flag.
Conflicts: src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala src/dotty/tools/dotc/core/Definitions.scala
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/transform/TailRec.scala22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala
index 543510dd7..b0d5c6438 100644
--- a/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/src/dotty/tools/dotc/transform/TailRec.scala
@@ -83,10 +83,11 @@ class TailRec extends TreeTransform with DenotTransformer {
override def name: String = "tailrec"
final val labelPrefix = "tailLabel"
+ final val labelFlags = Flags.Synthetic | Flags.Label
private def mkLabel(method: Symbol, tp: Type)(implicit c: Context): TermSymbol = {
val name = c.freshName(labelPrefix)
- c.newSymbol(method, name.toTermName, Flags.Synthetic, tp)
+ c.newSymbol(method, name.toTermName, labelFlags , tp)
}
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
@@ -95,7 +96,7 @@ class TailRec extends TreeTransform with DenotTransformer {
if (dd.symbol.isEffectivelyFinal) && !((dd.symbol is Flags.Accessor) || (rhs0 eq EmptyTree)) =>
val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass)
cpy.DefDef(tree, mods, name, tparams, vparamss0, tpt, rhs = {
- val owner = ctx.owner.enclosingClass
+ val owner = ctx.owner.enclosingClass.asClass
val thisTpe = owner.thisType
@@ -112,16 +113,25 @@ class TailRec extends TreeTransform with DenotTransformer {
// than first one will collect info about which transformations and rewritings should be applied
// and second one will actually apply,
// now this speculatively transforms tree and throws away result in many cases
- val res = tpd.Closure(label, args => {
+ val res = tpd.DefDef(label, args => {
val thiz = args.head.head
val argMapping: Map[Symbol, Tree] = (vparamss0.flatten.map(_.symbol) zip args.tail.flatten).toMap
val transformer = new TailRecElimination(dd.symbol, thiz, argMapping, owner, mandatory, label)
val rhs = transformer.transform(rhs0)(ctx.withPhase(ctx.phase.next))
rewrote = transformer.rewrote
rhs
- }, tparams)
-
- if (rewrote) res
+ })
+
+ if (rewrote) {
+ val call =
+ if (tparams.isEmpty) Ident(label.termRef)
+ else TypeApply(Ident(label.termRef), tparams)
+ Block(
+ List(res),
+ vparamss0.foldLeft(Apply(call, List(This(owner))))
+ {case (call, args) => Apply(call, args.map(x=> Ident(x.symbol.termRef)))}
+ )
+ }
else {
if (mandatory)
ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos)