@@ -429,10 +429,23 @@ class TailRec extends MiniPhase {
429429 assert(false , " We should never have gotten inside a pattern" )
430430 tree
431431
432- case tree : ValOrDefDef =>
432+ case tree : ValDef =>
433433 if (isMandatory) noTailTransform(tree.rhs)
434434 tree
435435
436+ case tree : DefDef =>
437+ if (isMandatory)
438+ if (tree.symbol.is(Synthetic ))
439+ noTailTransform(tree.rhs)
440+ else
441+ // We can't tail recurse through nested definitions, so don't want to propagate to child nodes
442+ // 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
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)
447+ tree
448+
436449 case _ : Super | _ : This | _ : Literal | _ : TypeTree | _ : TypeDef | EmptyTree =>
437450 tree
438451
@@ -446,14 +459,28 @@ class TailRec extends MiniPhase {
446459
447460 case Return (expr, from) =>
448461 val fromSym = from.symbol
449- val inTailPosition = ! fromSym.is(Label ) || tailPositionLabeledSyms.contains(fromSym)
462+ val inTailPosition = tailPositionLabeledSyms.contains(fromSym) // Label returns are only tail if the label is in tail position
463+ || (fromSym eq method) // Method returns are only tail if we are looking at the original method
450464 cpy.Return (tree)(transform(expr, inTailPosition), from)
451465
452466 case _ =>
453467 super .transform(tree)
454468 }
455469 }
456470 }
471+
472+ class NestedTailRecAlerter (method : Symbol , inner : Symbol ) extends TreeTraverser {
473+ override def traverse (tree : tpd.Tree )(using Context ): Unit =
474+ tree match {
475+ case a : Apply =>
476+ if (a.fun.symbol eq method) {
477+ report.warning(new TailrecNestedCall (method, inner), a.srcPos)
478+ }
479+ traverseChildren(tree)
480+ case _ =>
481+ traverseChildren(tree)
482+ }
483+ }
457484}
458485
459486object TailRec {
0 commit comments