@@ -286,11 +286,23 @@ class TailRec extends MiniPhase {
286
286
def yesTailTransform (tree : Tree )(using Context ): Tree =
287
287
transform(tree, tailPosition = true )
288
288
289
+ /** If not in tail position a tree traversal may not be needed.
290
+ *
291
+ * A recursive call may still be in tail position if within the return
292
+ * expression of a labeled block.
293
+ * A tree traversal may also be needed to report a failure to transform
294
+ * a recursive call of a @tailrec annotated method (i.e. `isMandatory`).
295
+ */
296
+ private def isTraversalNeeded =
297
+ isMandatory || tailPositionLabeledSyms.size > 0
298
+
289
299
def noTailTransform (tree : Tree )(using Context ): Tree =
290
- transform(tree, tailPosition = false )
300
+ if (isTraversalNeeded) transform(tree, tailPosition = false )
301
+ else tree
291
302
292
303
def noTailTransforms [Tr <: Tree ](trees : List [Tr ])(using Context ): List [Tr ] =
293
- trees.mapConserve(noTailTransform).asInstanceOf [List [Tr ]]
304
+ if (isTraversalNeeded) trees.mapConserve(noTailTransform).asInstanceOf [List [Tr ]]
305
+ else trees
294
306
295
307
override def transform (tree : Tree )(using Context ): Tree = {
296
308
/* Rewrite an Apply to be considered for tail call transformation. */
@@ -441,7 +453,7 @@ class TailRec extends MiniPhase {
441
453
442
454
case Return (expr, from) =>
443
455
val fromSym = from.symbol
444
- val inTailPosition = ! fromSym.is(Label ) || tailPositionLabeledSyms.contains(fromSym)
456
+ val inTailPosition = fromSym.is(Label ) && tailPositionLabeledSyms.contains(fromSym)
445
457
cpy.Return (tree)(transform(expr, inTailPosition), from)
446
458
447
459
case _ =>
0 commit comments