Skip to content

Commit ff730ca

Browse files
committed
Fix scala#5163: Report tailrec failures on recursive call targeting supertype
1 parent fe9d67e commit ff730ca

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-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
@@ -272,8 +272,8 @@ class TailRec extends MiniPhase {
272272
}
273273

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

279279
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import annotation.tailrec
2+
class UnrolledBuffer {
3+
def remove(idx: Int): Unit = ()
4+
@tailrec final def remove(idx: Int, count: Int): Unit =
5+
if (count > 0) {
6+
remove(idx)
7+
remove(idx, count - 1)
8+
}
9+
}

0 commit comments

Comments
 (0)