From 4d235ad2bd2a2741290ba6aa57de17409ffd3383 Mon Sep 17 00:00:00 2001 From: som-snytt Date: Mon, 14 Jul 2025 14:49:04 -0700 Subject: [PATCH] Check path of module prefix for tailrec (#23491) Fixes #23444 [Cherry-picked 9396bbe267b844a8cf4262ad375e1e4e96d0cf38] --- .../dotty/tools/dotc/transform/TailRec.scala | 5 ++++- tests/run/i23444.scala | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/run/i23444.scala diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala index e1bd3136f895..a9cfd40967e2 100644 --- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala +++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala @@ -344,7 +344,10 @@ class TailRec extends MiniPhase { case prefix: This if prefix.symbol == enclosingClass => // Avoid assigning `this = this` assignParamPairs - case prefix if prefix.symbol.is(Module) && prefix.symbol.moduleClass == enclosingClass => + case prefix + if prefix.symbol.is(Module) + && prefix.symbol.moduleClass == enclosingClass + && isPurePath(prefix) => // Avoid assigning `this = MyObject` assignParamPairs case _ => diff --git a/tests/run/i23444.scala b/tests/run/i23444.scala new file mode 100644 index 000000000000..ada7545e077f --- /dev/null +++ b/tests/run/i23444.scala @@ -0,0 +1,22 @@ + +import annotation.* + +class Path(action: () => Unit, parent: Option[Path]): + object O: + @tailrec + def apply(): Unit = + action() + + parent match + case Some(p) => + p.O.apply() + case None => + +@main def Test: Unit = + var counter = 0 + val fun = () => { + counter += 1 + if counter > 2 then throw AssertionError("bad loop") + } + val path = Path(fun, Some(Path(fun, None))) + path.O()