diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-09-29 17:06:49 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-10-11 06:39:09 +0200 |
commit | cb18aa3a4ff7eea8626153e27d7266f47851f80c (patch) | |
tree | 4c8cc07ce5bac916776bdd91f37f3576337e3d5e /src/dotty/tools/dotc/transform | |
parent | 5133dfcd00907e96472b14444bd87e0fa62b4dd3 (diff) | |
download | dotty-cb18aa3a4ff7eea8626153e27d7266f47851f80c.tar.gz dotty-cb18aa3a4ff7eea8626153e27d7266f47851f80c.tar.bz2 dotty-cb18aa3a4ff7eea8626153e27d7266f47851f80c.zip |
Allow extensions methods to play well with tailrec.
Diffstat (limited to 'src/dotty/tools/dotc/transform')
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TailRec.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeTransform.scala | 5 |
3 files changed, 13 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index c140bc9a5..4adbfe164 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -179,9 +179,9 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful extensionDefs(staticClass) = newC newC } - store += fullyParameterizedDef(extensionMeth, tree) + store += atGroupEnd(fullyParameterizedDef(extensionMeth, tree)(_)) cpy.DefDef(tree)(tree.mods, tree.name, tree.tparams, tree.vparamss, tree.tpt, - forwarder(extensionMeth, tree)) + atGroupEnd(forwarder(extensionMeth, tree)(_))) } else tree } } diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala index 16764de07..82b08ef5f 100644 --- a/src/dotty/tools/dotc/transform/TailRec.scala +++ b/src/dotty/tools/dotc/transform/TailRec.scala @@ -84,7 +84,9 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete case dd@DefDef(mods, name, tparams, vparamss0, tpt, rhs0) if (dd.symbol.isEffectivelyFinal) && !((dd.symbol is Flags.Accessor) || (rhs0 eq EmptyTree) || (dd.symbol is Flags.Label)) => val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass) - cpy.DefDef(dd)(rhs = { + atGroupEnd { implicit ctx: Context => + + cpy.DefDef(dd)(rhs = { val origMeth = tree.symbol val label = mkLabel(dd.symbol) @@ -99,7 +101,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete // now this speculatively transforms tree and throws away result in many cases val rhsSemiTransformed = { val transformer = new TailRecElimination(dd.symbol, owner, thisTpe, mandatory, label) - val rhs = transformer.transform(rhs0)(ctx.withPhase(ctx.phase.next)) + val rhs = atGroupEnd(transformer.transform(rhs0)(_)) rewrote = transformer.rewrote rhs } @@ -114,7 +116,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos) rhs0 } - }) + }) + } case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnotationClass) => ctx.error("TailRec optimisation not applicable, method is neither private nor final so can be overridden", d.pos) d diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index d06e1a0d9..9e04d03b9 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -134,6 +134,11 @@ object TreeTransforms { /** Transform single node using all transforms following the current one in this group */ def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transformSingle(tree, idx + 1) + def atGroupEnd[T](action : Context => T)(implicit ctx: Context, info: TransformerInfo) = { + val last = info.transformers(info.transformers.length - 1) + action(ctx.withPhase(last.phase.next)) + } + /** perform context-dependant initialization */ def init(implicit ctx: Context, info: TransformerInfo): Unit = {} } |