@@ -73,6 +73,20 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
73
73
final val labelPrefix = " tailLabel"
74
74
final val labelFlags = Flags .Synthetic | Flags .Label
75
75
76
+ /** Symbols of methods that have @tailrec annotatios inside */
77
+ private val methodsWithInnerAnnots = new collection.mutable.HashSet [Symbol ]()
78
+
79
+ override def transformUnit (tree : Tree )(implicit ctx : Context , info : TransformerInfo ): Tree = {
80
+ methodsWithInnerAnnots.clear()
81
+ tree
82
+ }
83
+
84
+ override def transformTyped (tree : Typed )(implicit ctx : Context , info : TransformerInfo ): Tree = {
85
+ if (tree.tpt.tpe.hasAnnotation(defn.TailrecAnnot ))
86
+ methodsWithInnerAnnots += ctx.owner.enclosingMethod
87
+ tree
88
+ }
89
+
76
90
private def mkLabel (method : Symbol , abstractOverClass : Boolean )(implicit c : Context ): TermSymbol = {
77
91
val name = c.freshName(labelPrefix)
78
92
@@ -137,10 +151,10 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
137
151
}
138
152
})
139
153
}
140
- case d : DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot ) =>
154
+ case d : DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot ) || methodsWithInnerAnnots.contains(d.symbol) =>
141
155
ctx.error(" TailRec optimisation not applicable, method is neither private nor final so can be overridden" , d.pos)
142
156
d
143
- case d if d.symbol.hasAnnotation(defn.TailrecAnnot ) =>
157
+ case d if d.symbol.hasAnnotation(defn.TailrecAnnot ) || methodsWithInnerAnnots.contains(d.symbol) =>
144
158
ctx.error(" TailRec optimisation not applicable, not a method" , d.pos)
145
159
d
146
160
case _ => tree
0 commit comments