diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-04-14 16:13:11 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-05-06 16:18:45 +0200 |
commit | 026b86da4c11a2e4933af00fe65cb2c37851ed3c (patch) | |
tree | 5057692a0f42e70a5c1499e02df384b82ba689ad /src | |
parent | 9e5cfe27f5d4b34b30102e78222c222ad7604414 (diff) | |
download | dotty-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.scala | 22 |
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) |