Skip to content

Commit

Permalink
Changes from PR.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucy Martin committed Apr 12, 2024
1 parent 73aae73 commit dea5b00
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 7 deletions.
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1914,10 +1914,10 @@ class TailrecNestedCall(definition: Symbol, innerDef: Symbol)(using Context)
}

def explain(using Context) =
"""Tail recursion is only validated and optimised directly in the definition
|any calls to the recursive method via an inner def cannot be validated as
"""Tail recursion is only validated and optimised directly in the definition.
|Any calls to the recursive method via an inner def cannot be validated as
|tail recursive, nor optimised if they are. To enable tail recursion from
|inner calls, mark the inner def as inline
|inner calls, mark the inner def as inline.
|""".stripMargin
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/transform/TailRec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ class TailRec extends MiniPhase {
if (tree.symbol.is(Synthetic))
noTailTransform(tree.rhs)
else
// We cant tail recurse through nested definitions, so dont want to propagate to child nodes
// We dont want to fail if there is a call that would recurse (as this would be a non self recurse), so dont
// We can't tail recurse through nested definitions, so don't want to propagate to child nodes
// We don't want to fail if there is a call that would recurse (as this would be a non self recurse), so don't
// want to call noTailTransform
// We can however warn in this case, as its likely in this situation that someone would expect a tail
// recursion optimization and enabling this to optimise would be a simple case of inlining the inner method
Expand All @@ -459,8 +459,8 @@ class TailRec extends MiniPhase {

case Return(expr, from) =>
val fromSym = from.symbol
val inTailPosition = (!fromSym.is(Label) || tailPositionLabeledSyms.contains(fromSym)) // Label returns are only tail if the label is in tail position
&& (!fromSym.is(Method) || (fromSym eq method)) // Method returns are only tail if we are looking at the original method
val inTailPosition = tailPositionLabeledSyms.contains(fromSym) // Label returns are only tail if the label is in tail position
|| (fromSym eq method) // Method returns are only tail if we are looking at the original method
cpy.Return(tree)(transform(expr, inTailPosition), from)

case _ =>
Expand Down
10 changes: 10 additions & 0 deletions tests/neg/i20105.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- [E195] Syntax Warning: tests\neg\i20105.scala:6:9 -------------------------------------------------------------------
6 | foo()
| ^^^^^
| The tail recursive def foo contains a recursive call inside the non-inlined inner def bar
|
| longer explanation available when compiling with `-explain`
-- [E097] Syntax Error: tests\neg\i20105.scala:3:4 ---------------------------------------------------------------------
3 |def foo(): Unit = // error
| ^
| TailRec optimisation not applicable, method foo contains no recursive calls
6 changes: 6 additions & 0 deletions tests/warn/i20105.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- [E195] Syntax Warning: tests\warn\i20105.scala:6:9 ------------------------------------------------------------------
6 | foo() // warn
| ^^^^^
| The tail recursive def foo contains a recursive call inside the non-inlined inner def bar
|
| longer explanation available when compiling with `-explain`

0 comments on commit dea5b00

Please sign in to comment.