Skip to content

Commit bbe0a97

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 5be1d73 commit bbe0a97

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
@@ -206,13 +206,13 @@ object Types {
206206
def loop(tp: Type): Boolean = tp match {
207207
case tp: TypeRef =>
208208
val sym = tp.symbol
209-
if (sym.isClass) sym.derivesFrom(cls) else loop(tp.superType): @tailrec
209+
if (sym.isClass) sym.derivesFrom(cls) else loop(tp.superType)
210210
case tp: TypeProxy =>
211-
loop(tp.underlying): @tailrec
211+
loop(tp.underlying)
212212
case tp: AndType =>
213-
loop(tp.tp1) || loop(tp.tp2): @tailrec
213+
loop(tp.tp1) || loop(tp.tp2)
214214
case tp: OrType =>
215-
loop(tp.tp1) && loop(tp.tp2): @tailrec
215+
loop(tp.tp1) && loop(tp.tp2)
216216
case tp: JavaArrayType =>
217217
cls == defn.ObjectClass
218218
case _ =>
@@ -389,16 +389,16 @@ object Types {
389389
*/
390390
final def classSymbol(implicit ctx: Context): Symbol = this match {
391391
case ConstantType(constant) =>
392-
constant.tpe.classSymbol: @tailrec
392+
constant.tpe.classSymbol
393393
case tp: TypeRef =>
394394
val sym = tp.symbol
395-
if (sym.isClass) sym else tp.superType.classSymbol: @tailrec
395+
if (sym.isClass) sym else tp.superType.classSymbol
396396
case tp: ClassInfo =>
397397
tp.cls
398398
case tp: SingletonType =>
399399
NoSymbol
400400
case tp: TypeProxy =>
401-
tp.underlying.classSymbol: @tailrec
401+
tp.underlying.classSymbol
402402
case AndType(l, r) =>
403403
val lsym = l.classSymbol
404404
val rsym = r.classSymbol
@@ -422,9 +422,9 @@ object Types {
422422
tp.cls :: Nil
423423
case tp: TypeRef =>
424424
val sym = tp.symbol
425-
if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols: @tailrec
425+
if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols
426426
case tp: TypeProxy =>
427-
tp.underlying.classSymbols: @tailrec
427+
tp.underlying.classSymbols
428428
case AndType(l, r) =>
429429
l.classSymbols union r.classSymbols
430430
case OrType(l, r) =>
@@ -465,7 +465,7 @@ object Types {
465465
case tp: ClassInfo =>
466466
tp.decls
467467
case tp: TypeProxy =>
468-
tp.underlying.decls: @tailrec
468+
tp.underlying.decls
469469
case _ =>
470470
EmptyScope
471471
}
@@ -711,7 +711,7 @@ object Types {
711711
val ns = tp.parent.memberNames(keepOnly, pre)
712712
if (keepOnly(pre, tp.refinedName)) ns + tp.refinedName else ns
713713
case tp: TypeProxy =>
714-
tp.underlying.memberNames(keepOnly, pre): @tailrec
714+
tp.underlying.memberNames(keepOnly, pre)
715715
case tp: AndType =>
716716
tp.tp1.memberNames(keepOnly, pre) | tp.tp2.memberNames(keepOnly, pre)
717717
case tp: OrType =>
@@ -1028,21 +1028,21 @@ object Types {
10281028
case tp: TypeRef =>
10291029
if (tp.symbol.isClass) tp
10301030
else tp.info match {
1031-
case TypeAlias(alias) => alias.dealias1(keep): @tailrec
1031+
case TypeAlias(alias) => alias.dealias1(keep)
10321032
case _ => tp
10331033
}
10341034
case app @ AppliedType(tycon, args) =>
10351035
val tycon1 = tycon.dealias1(keep)
1036-
if (tycon1 ne tycon) app.superType.dealias1(keep): @tailrec
1036+
if (tycon1 ne tycon) app.superType.dealias1(keep)
10371037
else this
10381038
case tp: TypeVar =>
10391039
val tp1 = tp.instanceOpt
1040-
if (tp1.exists) tp1.dealias1(keep): @tailrec else tp
1040+
if (tp1.exists) tp1.dealias1(keep) else tp
10411041
case tp: AnnotatedType =>
10421042
val tp1 = tp.parent.dealias1(keep)
10431043
if (keep(tp)(ctx)) tp.derivedAnnotatedType(tp1, tp.annot) else tp1
10441044
case tp: LazyRef =>
1045-
tp.ref.dealias1(keep): @tailrec
1045+
tp.ref.dealias1(keep)
10461046
case _ => this
10471047
}
10481048

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)