Skip to content

Commit 57ee4fa

Browse files
committed
Fix #5163: Report tailrec failures on recursive call targeting supertype
1 parent fa28ab1 commit 57ee4fa

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ class TailRec extends MiniPhase {
273273
}
274274

275275
val isRecursiveCall = calledMethod eq method
276-
// FIXME `(method.name eq sym)` is always false (Name vs Symbol). What is this trying to do?
277-
def isRecursiveSuperCall = (method.name eq calledMethod) &&
276+
def isRecursiveSuperCall = (method.name eq calledMethod.name) &&
277+
method.matches(calledMethod) &&
278278
enclosingClass.appliedRef.widen <:< prefix.tpe.widenDealias
279279

280280
if (isRecursiveCall) {

tests/neg-tailcall/tailrec-2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sealed abstract class Super[+A] {
88
class Bop1[+A](val element: A) extends Super[A] {
99

1010
@tailrec final def f[B >: A](mem: List[B]): List[B] = // error: TailRec optimisation not applicable
11-
(null: Super[A]).f(mem)
11+
(null: Super[A]).f(mem) // error: recursive call targeting a supertype
1212

1313
@tailrec final def f1[B >: A](mem: List[B]): List[B] = this.g(mem) // error: TailRec optimisation not applicable
1414
}

tests/pos/tailcall/i5163.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import annotation.tailrec
2+
3+
class UnrolledBuffer {
4+
def remove(idx: Int): Unit = ()
5+
@tailrec final def remove(idx: Int, count: Int): Unit =
6+
if (count > 0) {
7+
remove(idx) // ok: not a recursive call
8+
remove(idx, count - 1)
9+
}
10+
}

0 commit comments

Comments
 (0)