@@ -277,11 +277,23 @@ class TailRec extends MiniPhase {
277
277
def yesTailTransform (tree : Tree )(using Context ): Tree =
278
278
transform(tree, tailPosition = true )
279
279
280
+ /** If not in tail position a tree traversal may not be needed.
281
+ *
282
+ * A recursive call may still be in tail position if within the return
283
+ * expression of a labeled block.
284
+ * A tree traversal may also be needed to report a failure to transform
285
+ * a recursive call of a @tailrec annotated method (i.e. `isMandatory`).
286
+ */
287
+ private def isTraversalNeeded =
288
+ isMandatory || tailPositionLabeledSyms.size > 0
289
+
280
290
def noTailTransform (tree : Tree )(using Context ): Tree =
281
- transform(tree, tailPosition = false )
291
+ if (isTraversalNeeded) transform(tree, tailPosition = false )
292
+ else tree
282
293
283
294
def noTailTransforms [Tr <: Tree ](trees : List [Tr ])(using Context ): List [Tr ] =
284
- trees.mapConserve(noTailTransform).asInstanceOf [List [Tr ]]
295
+ if (isTraversalNeeded) trees.mapConserve(noTailTransform).asInstanceOf [List [Tr ]]
296
+ else trees
285
297
286
298
override def transform (tree : Tree )(using Context ): Tree = {
287
299
/* Rewrite an Apply to be considered for tail call transformation. */
@@ -432,7 +444,7 @@ class TailRec extends MiniPhase {
432
444
433
445
case Return (expr, from) =>
434
446
val fromSym = from.symbol
435
- val inTailPosition = ! fromSym.is(Label ) || tailPositionLabeledSyms.contains(fromSym)
447
+ val inTailPosition = fromSym.is(Label ) && tailPositionLabeledSyms.contains(fromSym)
436
448
cpy.Return (tree)(transform(expr, inTailPosition), from)
437
449
438
450
case _ =>
0 commit comments