Skip to content

Commit 78b6070

Browse files
authored
Merge pull request #14942 from dotty-staging/re-revert-#14067
Re-revert #14067
2 parents 4c61dae + 675eaaf commit 78b6070

File tree

3 files changed

+76
-15
lines changed

3 files changed

+76
-15
lines changed

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

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -286,23 +286,11 @@ class TailRec extends MiniPhase {
286286
def yesTailTransform(tree: Tree)(using Context): Tree =
287287
transform(tree, tailPosition = true)
288288

289-
/** If not in tail position a tree traversal may not be needed.
290-
*
291-
* A recursive call may still be in tail position if within the return
292-
* expression of a labeled block.
293-
* A tree traversal may also be needed to report a failure to transform
294-
* a recursive call of a @tailrec annotated method (i.e. `isMandatory`).
295-
*/
296-
private def isTraversalNeeded =
297-
isMandatory || tailPositionLabeledSyms.size > 0
298-
299289
def noTailTransform(tree: Tree)(using Context): Tree =
300-
if (isTraversalNeeded) transform(tree, tailPosition = false)
301-
else tree
290+
transform(tree, tailPosition = false)
302291

303292
def noTailTransforms[Tr <: Tree](trees: List[Tr])(using Context): List[Tr] =
304-
if (isTraversalNeeded) trees.mapConserve(noTailTransform).asInstanceOf[List[Tr]]
305-
else trees
293+
trees.mapConserve(noTailTransform).asInstanceOf[List[Tr]]
306294

307295
override def transform(tree: Tree)(using Context): Tree = {
308296
/* Rewrite an Apply to be considered for tail call transformation. */
@@ -456,7 +444,7 @@ class TailRec extends MiniPhase {
456444

457445
case Return(expr, from) =>
458446
val fromSym = from.symbol
459-
val inTailPosition = fromSym.is(Label) && tailPositionLabeledSyms.contains(fromSym)
447+
val inTailPosition = !fromSym.is(Label) || tailPositionLabeledSyms.contains(fromSym)
460448
cpy.Return(tree)(transform(expr, inTailPosition), from)
461449

462450
case _ =>

tests/run/tailrec-return.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
6
2+
false
3+
true
4+
false
5+
true
6+
Ada Lovelace, Alan Turing
7+
List(9, 10)

tests/run/tailrec-return.scala

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
object Test:
2+
3+
@annotation.tailrec
4+
def sum(n: Int, acc: Int = 0): Int =
5+
if n != 0 then return sum(n - 1, acc + n)
6+
acc
7+
8+
@annotation.tailrec
9+
def isEven(n: Int): Boolean =
10+
if n != 0 && n != 1 then return isEven(n - 2)
11+
if n == 1 then return false
12+
true
13+
14+
@annotation.tailrec
15+
def isEvenApply(n: Int): Boolean =
16+
// Return inside an `Apply.fun`
17+
(
18+
if n != 0 && n != 1 then return isEvenApply(n - 2)
19+
else if n == 1 then return false
20+
else (x: Boolean) => x
21+
)(true)
22+
23+
@annotation.tailrec
24+
def isEvenWhile(n: Int): Boolean =
25+
// Return inside a `WhileDo.cond`
26+
while(
27+
if n != 0 && n != 1 then return isEvenWhile(n - 2)
28+
else if n == 1 then return false
29+
else true
30+
) {}
31+
true
32+
33+
@annotation.tailrec
34+
def isEvenReturn(n: Int): Boolean =
35+
// Return inside a `Return`
36+
return
37+
if n != 0 && n != 1 then return isEvenReturn(n - 2)
38+
else if n == 1 then return false
39+
else true
40+
41+
@annotation.tailrec
42+
def names(l: List[(String, String) | Null], acc: List[String] = Nil): List[String] =
43+
l match
44+
case Nil => acc.reverse
45+
case x :: xs =>
46+
if x == null then return names(xs, acc)
47+
48+
val displayName = x._1 + " " + x._2
49+
names(xs, displayName :: acc)
50+
51+
def nonTail(l: List[Int]): List[Int] =
52+
l match
53+
case Nil => Nil
54+
case x :: xs =>
55+
// The call to nonTail should *not* be eliminated
56+
(x + 1) :: nonTail(xs)
57+
58+
59+
def main(args: Array[String]): Unit =
60+
println(sum(3))
61+
println(isEven(5))
62+
println(isEvenApply(6))
63+
println(isEvenWhile(7))
64+
println(isEvenReturn(8))
65+
println(names(List(("Ada", "Lovelace"), null, ("Alan", "Turing"))).mkString(", "))
66+
println(nonTail(List(8, 9)))

0 commit comments

Comments
 (0)