Skip to content

Commit 7b1e8d9

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 b8be1e7 commit 7b1e8d9

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
@@ -74,20 +74,6 @@ class TailRec extends MiniPhase {
7474

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

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

@@ -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
@@ -238,8 +224,7 @@ class TailRec extends MiniPhase {
238224
Apply(noTailTransform(call), arguments)
239225

240226
def fail(reason: String) = {
241-
def required = tree.getAttachment(TailRecCallSiteKey).isDefined
242-
if (isMandatory || required) c.error(s"Cannot rewrite recursive call: $reason", tree.pos)
227+
if (isMandatory) c.error(s"Cannot rewrite recursive call: $reason", tree.pos)
243228
else c.debuglog("Cannot rewrite recursive call at: " + tree.pos + " because: " + reason)
244229
continue
245230
}
@@ -359,6 +344,4 @@ object TailRec {
359344

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

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)