Skip to content

Commit f510492

Browse files
author
Lucy Martin
committed
Potential options for different handling of defined and implicit inner methods
1 parent 15056b5 commit f510492

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,15 @@ class TailRec extends MiniPhase {
438438

439439
case tree: DefDef =>
440440
if (isMandatory)
441-
// We cant tail recurse through nested definitions, so dont want to propagate to child nodes
442-
// We dont want to fail if there is a call that would recurse (as this would be a non self recurse), so dont
443-
// want to call noTailTransform
444-
// We can however warn in this case, as its likely in this situation that someone would expect a tail
445-
// recursion optimization and enabling this to optimise would be a simple case of inlining the inner method
446-
new NestedTailRecAlerter(method, tree.symbol).traverse(tree)
441+
if (tree.symbol.is(Synthetic))
442+
noTailTransform(tree.rhs)
443+
else
444+
// We cant tail recurse through nested definitions, so dont want to propagate to child nodes
445+
// We dont want to fail if there is a call that would recurse (as this would be a non self recurse), so dont
446+
// want to call noTailTransform
447+
// We can however warn in this case, as its likely in this situation that someone would expect a tail
448+
// recursion optimization and enabling this to optimise would be a simple case of inlining the inner method
449+
new NestedTailRecAlerter(method, tree.symbol).traverse(tree)
447450
tree
448451

449452
case _: Super | _: This | _: Literal | _: TypeTree | _: TypeDef | EmptyTree =>

tests/neg/i20105.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import scala.annotation.tailrec
12
@tailrec
2-
def foo(): Unit =
3+
def foo(): Unit = // error
34
def bar(): Unit =
45
if (???)
56
foo()

tests/neg/i5397.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ object Test {
1616
rec3 // error: not in tail position
1717
})
1818

19-
@tailrec def rec4: Unit = {
20-
def local = rec4 // error: not in tail position
19+
// This is technically not breaching tail recursion as rec4 does not call itself, local does
20+
// This instead fails due to having no tail recursion at all
21+
@tailrec def rec4: Unit = { // error: no recursive calls
22+
def local = rec4
2123
}
2224

2325
@tailrec def rec5: Int = {

tests/warn/i20105.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import scala.annotation.tailrec
12
@tailrec
23
def foo(): Unit =
34
def bar(): Unit =

0 commit comments

Comments
 (0)