@@ -83,10 +83,11 @@ class TailRec extends TreeTransform with DenotTransformer {
83
83
override def name : String = " tailrec"
84
84
85
85
final val labelPrefix = " tailLabel"
86
+ final val labelFlags = Flags .Synthetic | Flags .Label
86
87
87
88
private def mkLabel (method : Symbol , tp : Type )(implicit c : Context ): TermSymbol = {
88
89
val name = c.freshName(labelPrefix)
89
- c.newSymbol(method, name.toTermName, Flags . Synthetic , tp)
90
+ c.newSymbol(method, name.toTermName, labelFlags , tp)
90
91
}
91
92
92
93
override def transformDefDef (tree : tpd.DefDef )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
@@ -95,7 +96,7 @@ class TailRec extends TreeTransform with DenotTransformer {
95
96
if (dd.symbol.isEffectivelyFinal) && ! ((dd.symbol is Flags .Accessor ) || (rhs0 eq EmptyTree )) =>
96
97
val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass )
97
98
cpy.DefDef (tree, mods, name, tparams, vparamss0, tpt, rhs = {
98
- val owner = ctx.owner.enclosingClass
99
+ val owner = ctx.owner.enclosingClass.asClass
99
100
100
101
val thisTpe = owner.thisType
101
102
@@ -112,16 +113,25 @@ class TailRec extends TreeTransform with DenotTransformer {
112
113
// than first one will collect info about which transformations and rewritings should be applied
113
114
// and second one will actually apply,
114
115
// 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 => {
116
117
val thiz = args.head.head
117
118
val argMapping : Map [Symbol , Tree ] = (vparamss0.flatten.map(_.symbol) zip args.tail.flatten).toMap
118
119
val transformer = new TailRecElimination (dd.symbol, thiz, argMapping, owner, mandatory, label)
119
120
val rhs = transformer.transform(rhs0)(ctx.withPhase(ctx.phase.next))
120
121
rewrote = transformer.rewrote
121
122
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
+ }
125
135
else {
126
136
if (mandatory)
127
137
ctx.error(" TailRec optimisation not applicable, method not tail recursive" , dd.pos)
0 commit comments