Skip to content

Commit 026b86d

Browse files
committed
Fix TailRec to use Label flag.
Conflicts: src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala src/dotty/tools/dotc/core/Definitions.scala
1 parent 9e5cfe2 commit 026b86d

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ class TailRec extends TreeTransform with DenotTransformer {
8383
override def name: String = "tailrec"
8484

8585
final val labelPrefix = "tailLabel"
86+
final val labelFlags = Flags.Synthetic | Flags.Label
8687

8788
private def mkLabel(method: Symbol, tp: Type)(implicit c: Context): TermSymbol = {
8889
val name = c.freshName(labelPrefix)
89-
c.newSymbol(method, name.toTermName, Flags.Synthetic, tp)
90+
c.newSymbol(method, name.toTermName, labelFlags , tp)
9091
}
9192

9293
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
@@ -95,7 +96,7 @@ class TailRec extends TreeTransform with DenotTransformer {
9596
if (dd.symbol.isEffectivelyFinal) && !((dd.symbol is Flags.Accessor) || (rhs0 eq EmptyTree)) =>
9697
val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass)
9798
cpy.DefDef(tree, mods, name, tparams, vparamss0, tpt, rhs = {
98-
val owner = ctx.owner.enclosingClass
99+
val owner = ctx.owner.enclosingClass.asClass
99100

100101
val thisTpe = owner.thisType
101102

@@ -112,16 +113,25 @@ class TailRec extends TreeTransform with DenotTransformer {
112113
// than first one will collect info about which transformations and rewritings should be applied
113114
// and second one will actually apply,
114115
// now this speculatively transforms tree and throws away result in many cases
115-
val res = tpd.Closure(label, args => {
116+
val res = tpd.DefDef(label, args => {
116117
val thiz = args.head.head
117118
val argMapping: Map[Symbol, Tree] = (vparamss0.flatten.map(_.symbol) zip args.tail.flatten).toMap
118119
val transformer = new TailRecElimination(dd.symbol, thiz, argMapping, owner, mandatory, label)
119120
val rhs = transformer.transform(rhs0)(ctx.withPhase(ctx.phase.next))
120121
rewrote = transformer.rewrote
121122
rhs
122-
}, tparams)
123-
124-
if (rewrote) res
123+
})
124+
125+
if (rewrote) {
126+
val call =
127+
if (tparams.isEmpty) Ident(label.termRef)
128+
else TypeApply(Ident(label.termRef), tparams)
129+
Block(
130+
List(res),
131+
vparamss0.foldLeft(Apply(call, List(This(owner))))
132+
{case (call, args) => Apply(call, args.map(x=> Ident(x.symbol.termRef)))}
133+
)
134+
}
125135
else {
126136
if (mandatory)
127137
ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos)

0 commit comments

Comments
 (0)