Skip to content

Commit cb18aa3

Browse files
committed
Allow extensions methods to play well with tailrec.
1 parent 5133dfc commit cb18aa3

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

src/dotty/tools/dotc/transform/ExtensionMethods.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
179179
extensionDefs(staticClass) = newC
180180
newC
181181
}
182-
store += fullyParameterizedDef(extensionMeth, tree)
182+
store += atGroupEnd(fullyParameterizedDef(extensionMeth, tree)(_))
183183
cpy.DefDef(tree)(tree.mods, tree.name, tree.tparams, tree.vparamss, tree.tpt,
184-
forwarder(extensionMeth, tree))
184+
atGroupEnd(forwarder(extensionMeth, tree)(_)))
185185
} else tree
186186
}
187187
}

src/dotty/tools/dotc/transform/TailRec.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
8484
case dd@DefDef(mods, name, tparams, vparamss0, tpt, rhs0)
8585
if (dd.symbol.isEffectivelyFinal) && !((dd.symbol is Flags.Accessor) || (rhs0 eq EmptyTree) || (dd.symbol is Flags.Label)) =>
8686
val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass)
87-
cpy.DefDef(dd)(rhs = {
87+
atGroupEnd { implicit ctx: Context =>
88+
89+
cpy.DefDef(dd)(rhs = {
8890

8991
val origMeth = tree.symbol
9092
val label = mkLabel(dd.symbol)
@@ -99,7 +101,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
99101
// now this speculatively transforms tree and throws away result in many cases
100102
val rhsSemiTransformed = {
101103
val transformer = new TailRecElimination(dd.symbol, owner, thisTpe, mandatory, label)
102-
val rhs = transformer.transform(rhs0)(ctx.withPhase(ctx.phase.next))
104+
val rhs = atGroupEnd(transformer.transform(rhs0)(_))
103105
rewrote = transformer.rewrote
104106
rhs
105107
}
@@ -114,7 +116,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
114116
ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos)
115117
rhs0
116118
}
117-
})
119+
})
120+
}
118121
case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnotationClass) =>
119122
ctx.error("TailRec optimisation not applicable, method is neither private nor final so can be overridden", d.pos)
120123
d

src/dotty/tools/dotc/transform/TreeTransform.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ object TreeTransforms {
134134
/** Transform single node using all transforms following the current one in this group */
135135
def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transformSingle(tree, idx + 1)
136136

137+
def atGroupEnd[T](action : Context => T)(implicit ctx: Context, info: TransformerInfo) = {
138+
val last = info.transformers(info.transformers.length - 1)
139+
action(ctx.withPhase(last.phase.next))
140+
}
141+
137142
/** perform context-dependant initialization */
138143
def init(implicit ctx: Context, info: TransformerInfo): Unit = {}
139144
}

0 commit comments

Comments
 (0)