Skip to content

Commit f102203

Browse files
committed
Feature Removal: Do not check call-site @tailrec anymore.
This feature does not exist in Scala 2, and was never documented in Scala 3. Its only internal use comes from a swiping commit that added as many `@tailrec` annotations as possible all over the codebase: see be5720c. Supporting that feature became problematic when TailRec was moved after erasure, because we needed an attachment to remember call-site `@tailrec` annotations, which would otherwise be removed by erasure. This commit removes the feature, on the grounds that its cost/benefit is too high.
1 parent b1008d8 commit f102203

File tree

7 files changed

+17
-107
lines changed

7 files changed

+17
-107
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ class Compiler {
9191
new ResolveSuper, // Implement super accessors and add forwarders to trait methods
9292
new PrimitiveForwarders, // Add forwarders to trait methods that have a mismatch between generic and primitives
9393
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
94-
new RecordTailRecCallSites, // Records call-site @tailrec annotations as attachments
9594
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
9695
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
9796
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,17 @@ object Types {
208208
def loop(tp: Type): Boolean = tp match {
209209
case tp: TypeRef =>
210210
val sym = tp.symbol
211-
if (sym.isClass) sym.derivesFrom(cls) else loop(tp.superType): @tailrec
211+
if (sym.isClass) sym.derivesFrom(cls) else loop(tp.superType)
212212
case tp: AppliedType =>
213213
tp.superType.derivesFrom(cls)
214214
case tp: MatchType =>
215215
tp.bound.derivesFrom(cls) || tp.reduced.derivesFrom(cls)
216216
case tp: TypeProxy =>
217-
loop(tp.underlying): @tailrec
217+
loop(tp.underlying)
218218
case tp: AndType =>
219-
loop(tp.tp1) || loop(tp.tp2): @tailrec
219+
loop(tp.tp1) || loop(tp.tp2)
220220
case tp: OrType =>
221-
loop(tp.tp1) && loop(tp.tp2): @tailrec
221+
loop(tp.tp1) && loop(tp.tp2)
222222
case tp: JavaArrayType =>
223223
cls == defn.ObjectClass
224224
case _ =>
@@ -403,16 +403,16 @@ object Types {
403403
*/
404404
final def classSymbol(implicit ctx: Context): Symbol = this match {
405405
case ConstantType(constant) =>
406-
constant.tpe.classSymbol: @tailrec
406+
constant.tpe.classSymbol
407407
case tp: TypeRef =>
408408
val sym = tp.symbol
409-
if (sym.isClass) sym else tp.superType.classSymbol: @tailrec
409+
if (sym.isClass) sym else tp.superType.classSymbol
410410
case tp: ClassInfo =>
411411
tp.cls
412412
case tp: SingletonType =>
413413
NoSymbol
414414
case tp: TypeProxy =>
415-
tp.underlying.classSymbol: @tailrec
415+
tp.underlying.classSymbol
416416
case AndType(l, r) =>
417417
val lsym = l.classSymbol
418418
val rsym = r.classSymbol
@@ -436,9 +436,9 @@ object Types {
436436
tp.cls :: Nil
437437
case tp: TypeRef =>
438438
val sym = tp.symbol
439-
if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols: @tailrec
439+
if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols
440440
case tp: TypeProxy =>
441-
tp.underlying.classSymbols: @tailrec
441+
tp.underlying.classSymbols
442442
case AndType(l, r) =>
443443
l.classSymbols union r.classSymbols
444444
case OrType(l, r) =>
@@ -479,7 +479,7 @@ object Types {
479479
case tp: ClassInfo =>
480480
tp.decls
481481
case tp: TypeProxy =>
482-
tp.underlying.decls: @tailrec
482+
tp.underlying.decls
483483
case _ =>
484484
EmptyScope
485485
}
@@ -725,7 +725,7 @@ object Types {
725725
val ns = tp.parent.memberNames(keepOnly, pre)
726726
if (keepOnly(pre, tp.refinedName)) ns + tp.refinedName else ns
727727
case tp: TypeProxy =>
728-
tp.underlying.memberNames(keepOnly, pre): @tailrec
728+
tp.underlying.memberNames(keepOnly, pre)
729729
case tp: AndType =>
730730
tp.tp1.memberNames(keepOnly, pre) | tp.tp2.memberNames(keepOnly, pre)
731731
case tp: OrType =>
@@ -1042,21 +1042,21 @@ object Types {
10421042
case tp: TypeRef =>
10431043
if (tp.symbol.isClass) tp
10441044
else tp.info match {
1045-
case TypeAlias(alias) => alias.dealias1(keep): @tailrec
1045+
case TypeAlias(alias) => alias.dealias1(keep)
10461046
case _ => tp
10471047
}
10481048
case app @ AppliedType(tycon, args) =>
10491049
val tycon1 = tycon.dealias1(keep)
1050-
if (tycon1 ne tycon) app.superType.dealias1(keep): @tailrec
1050+
if (tycon1 ne tycon) app.superType.dealias1(keep)
10511051
else this
10521052
case tp: TypeVar =>
10531053
val tp1 = tp.instanceOpt
1054-
if (tp1.exists) tp1.dealias1(keep): @tailrec else tp
1054+
if (tp1.exists) tp1.dealias1(keep) else tp
10551055
case tp: AnnotatedType =>
10561056
val tp1 = tp.parent.dealias1(keep)
10571057
if (keep(tp)(ctx)) tp.derivedAnnotatedType(tp1, tp.annot) else tp1
10581058
case tp: LazyRef =>
1059-
tp.ref.dealias1(keep): @tailrec
1059+
tp.ref.dealias1(keep)
10601060
case _ => this
10611061
}
10621062

compiler/src/dotty/tools/dotc/transform/RecordTailRecCallSites.scala

Lines changed: 0 additions & 42 deletions
This file was deleted.

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

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,6 @@ class TailRec extends MiniPhase {
7575

7676
final val labelFlags = Flags.Synthetic | Flags.Label | Flags.Method
7777

78-
/** Symbols of methods that have @tailrec annotatios inside */
79-
private val methodsWithInnerAnnots = new collection.mutable.HashSet[Symbol]()
80-
81-
override def transformUnit(tree: Tree)(implicit ctx: Context): Tree = {
82-
methodsWithInnerAnnots.clear()
83-
tree
84-
}
85-
86-
override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
87-
if (tree.getAttachment(TailRecCallSiteKey).isDefined)
88-
methodsWithInnerAnnots += ctx.owner.enclosingMethod
89-
tree
90-
}
91-
9278
private def mkLabel(method: Symbol)(implicit ctx: Context): TermSymbol = {
9379
val name = TailLabelName.fresh()
9480

@@ -181,7 +167,7 @@ class TailRec extends MiniPhase {
181167
dd.rhs
182168
}
183169
})
184-
case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot) || methodsWithInnerAnnots.contains(d.symbol) =>
170+
case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot) =>
185171
ctx.error(TailrecNotApplicable(sym), sym.pos)
186172
d
187173
case _ => tree
@@ -239,8 +225,7 @@ class TailRec extends MiniPhase {
239225
tpd.cpy.Apply(tree)(noTailTransform(call), arguments)
240226

241227
def fail(reason: String) = {
242-
def required = tree.getAttachment(TailRecCallSiteKey).isDefined
243-
if (isMandatory || required) c.error(s"Cannot rewrite recursive call: $reason", tree.pos)
228+
if (isMandatory) c.error(s"Cannot rewrite recursive call: $reason", tree.pos)
244229
else c.debuglog("Cannot rewrite recursive call at: " + tree.pos + " because: " + reason)
245230
continue
246231
}
@@ -360,6 +345,4 @@ object TailRec {
360345

361346
final val noTailContext = new TailContext(false)
362347
final val yesTailContext = new TailContext(true)
363-
364-
object TailRecCallSiteKey extends Property.StickyKey[Unit]
365348
}

tests/neg-tailcall/i1221.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/neg-tailcall/i1221b.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/pos/tailcall/i1221.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)