Skip to content

Commit 73aae73

Browse files
author
Lucy Martin
committed
Potential options for different handling of defined and implicit inner methods
1 parent e6156fe commit 73aae73

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
@@ -435,12 +435,15 @@ class TailRec extends MiniPhase {
435435

436436
case tree: DefDef =>
437437
if (isMandatory)
438-
// We cant tail recurse through nested definitions, so dont want to propagate to child nodes
439-
// We dont want to fail if there is a call that would recurse (as this would be a non self recurse), so dont
440-
// want to call noTailTransform
441-
// We can however warn in this case, as its likely in this situation that someone would expect a tail
442-
// recursion optimization and enabling this to optimise would be a simple case of inlining the inner method
443-
new NestedTailRecAlerter(method, tree.symbol).traverse(tree)
438+
if (tree.symbol.is(Synthetic))
439+
noTailTransform(tree.rhs)
440+
else
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)
444447
tree
445448

446449
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)