From 7f2a883c314ddbec63f9d3612d9c07d9d423aa94 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 8 Jul 2025 13:25:31 -0700 Subject: [PATCH] Check path of module prefix for tailrec --- .../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 472ed78bfb6b..08c2c6a015c0 100644 --- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala +++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala @@ -346,7 +346,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()