File tree 13 files changed +46
-81
lines changed
compiler/src/dotty/tools/dotc/transform
13 files changed +46
-81
lines changed Original file line number Diff line number Diff line change @@ -237,8 +237,9 @@ class TailRec extends MiniPhase {
237
237
}
238
238
else fail(" it is not in tail position" )
239
239
} else {
240
- // FIXME `(method.name eq call)` is always false (Name vs Symbol). What is this trying to do?
241
- val receiverIsSuper = (method.name eq call) && enclosingClass.appliedRef.widen <:< prefix.tpe.widenDealias
240
+ val receiverIsSuper = (method.name eq call.name) &&
241
+ method.matches(call) &&
242
+ enclosingClass.appliedRef.widen <:< prefix.tpe.widenDealias
242
243
243
244
if (receiverIsSuper) fail(" it contains a recursive call targeting a supertype" )
244
245
else continue
Load Diff This file was deleted.
Original file line number Diff line number Diff line change
1
+ import annotation .tailrec
2
+
1
3
object Test1772B {
2
- @ annotation. tailrec
4
+ @ tailrec
3
5
def bar : Nothing = { // error: TailRec optimisation not applicable
4
6
try {
5
7
throw new RuntimeException
@@ -10,7 +12,7 @@ object Test1772B {
10
12
}
11
13
}
12
14
13
- @ annotation. tailrec
15
+ @ tailrec
14
16
def baz : Nothing = { // error: TailRec optimisation not applicable
15
17
try {
16
18
throw new RuntimeException
@@ -21,7 +23,7 @@ object Test1772B {
21
23
}
22
24
}
23
25
24
- @ annotation. tailrec
26
+ @ tailrec
25
27
def boz : Nothing = { // error: TailRec optimisation not applicable
26
28
try {
27
29
throw new RuntimeException
@@ -30,7 +32,7 @@ object Test1772B {
30
32
}
31
33
}
32
34
33
- @ annotation. tailrec
35
+ @ tailrec
34
36
def bez : Nothing = { // error: TailRec optimisation not applicable
35
37
try {
36
38
bez // error: it is not in tail position
@@ -40,7 +42,7 @@ object Test1772B {
40
42
}
41
43
42
44
// the `liftedTree` local method will prevent a tail call here.
43
- @ annotation. tailrec
45
+ @ tailrec
44
46
def bar (i : Int ) : Int = { // error: TailRec optimisation not applicable
45
47
if (i == 0 ) 0
46
48
else 1 + (try {
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1
1
object Test {
2
- @ annotation.tailrec def foo () = 5 // error
2
+ @ annotation.tailrec def foo () = 5 // error: not recursive
3
3
}
Load Diff This file was deleted.
Original file line number Diff line number Diff line change
1
+ import annotation .tailrec
2
+
1
3
class Bad [X , Y ](val v : Int ) extends AnyVal {
2
- @ annotation. tailrec final def notTailPos [Z ](a : Int )(b : String ): Unit = { // error
3
- this .notTailPos[Z ](a)(b) // error
4
+ @ tailrec final def notTailPos [Z ](a : Int )(b : String ): Unit = { // error: TailRec optimisation not applicable
5
+ this .notTailPos[Z ](a)(b) // error: it is not in tail position
4
6
println(" tail" )
5
7
}
6
8
7
- @ annotation. tailrec final def differentTypeArgs : Unit = {
9
+ @ tailrec final def differentTypeArgs : Unit = {
8
10
{(); new Bad [String , Unit ](0 )}.differentTypeArgs
9
11
}
10
12
}
Load Diff This file was deleted.
Original file line number Diff line number Diff line change
1
+ import annotation .tailrec
2
+
1
3
sealed abstract class Super [+ A ] {
2
4
def f [B >: A ](mem : List [B ]) : List [B ]
3
5
def g (mem : List [_]) = ???
4
6
}
5
7
// This one should fail, target is a supertype
6
8
class Bop1 [+ A ](val element : A ) extends Super [A ] {
7
9
8
- @ annotation.tailrec final def f [B >: A ](mem : List [B ]): List [B ] = (null : Super [A ]).f(mem)
9
- @ annotation.tailrec final def f1 [B >: A ](mem : List [B ]): List [B ] = this .g(mem)
10
+ @ tailrec final def f [B >: A ](mem : List [B ]): List [B ] = // error: TailRec optimisation not applicable
11
+ (null : Super [A ]).f(mem) // error: recursive call targeting a supertype
12
+
13
+ @ tailrec final def f1 [B >: A ](mem : List [B ]): List [B ] = this .g(mem) // error: TailRec optimisation not applicable
10
14
}
11
15
// These succeed
12
16
class Bop2 [+ A ](val element : A ) extends Super [A ] {
13
- @ annotation. tailrec final def f [B >: A ](mem : List [B ]): List [B ] = (null : Bop2 [A ]).f(mem)
17
+ @ tailrec final def f [B >: A ](mem : List [B ]): List [B ] = (null : Bop2 [A ]).f(mem)
14
18
}
15
19
object Bop3 extends Super [Nothing ] {
16
- @ annotation. tailrec final def f [B ](mem : List [B ]): List [B ] = (???: Bop3 .type ).f(mem) // error // error
20
+ @ tailrec final def f [B ](mem : List [B ]): List [B ] = (??? : Bop3 .type ).f(mem)
17
21
}
18
22
class Bop4 [+ A ](val element : A ) extends Super [A ] {
19
- @ annotation. tailrec final def f [B >: A ](mem : List [B ]): List [B ] = Other .f[A ].f(mem)
23
+ @ tailrec final def f [B >: A ](mem : List [B ]): List [B ] = Other .f[A ].f(mem)
20
24
}
21
25
22
26
object Other {
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1
1
import annotation .tailrec
2
2
3
3
object Test {
4
- @ tailrec private def quux (xs : List [String ]): List [String ] = quux(quux(xs)) // error
4
+ @ tailrec private def quux (xs : List [String ]): List [String ] =
5
+ quux(
6
+ quux(xs) // error: not in tail position
7
+ )
5
8
@ tailrec private def quux2 (xs : List [String ]): List [String ] = xs match {
6
- case x1 :: x2 :: rest => quux2(x1 :: quux2(rest)) // error
7
- case _ => Nil
9
+ case x1 :: x2 :: rest => quux2(
10
+ x1 :: quux2(rest)) // error: not in tail position
11
+ case _ => Nil
8
12
}
9
13
@ tailrec private def quux3 (xs : List [String ]): Boolean = xs match {
10
- case x :: xs if quux3(List (" abc" )) => quux3(xs) // error
11
- case _ => false
14
+ case x :: xs if quux3(List (" abc" )) => // error: not in tail position
15
+ quux3(xs)
16
+ case _ => false
12
17
}
13
18
}
14
19
Load Diff This file was deleted.
Original file line number Diff line number Diff line change
1
+ import annotation .tailrec
2
+
3
+ class UnrolledBuffer {
4
+ def remove (idx : Int ): Unit = ()
5
+
6
+ @ tailrec final def remove (idx : Int , count : Int ): Unit =
7
+ if (count > 0 ) {
8
+ remove(idx)
9
+ remove(idx, count - 1 )
10
+ }
11
+ }
You can’t perform that action at this time.
0 commit comments