Skip to content

Commit c3c7cd3

Browse files
Merge pull request #12139 from dotty-staging/fix-12116
Avoid exponential retries on inlining overflow
2 parents 3bcdc34 + 6601a5e commit c3c7cd3

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,9 @@ object Contexts {
922922

923923
private[core] var denotTransformers: Array[DenotTransformer] = _
924924

925+
/** Flag to suppress inlining, set after overflow */
926+
private[dotc] var stopInlining: Boolean = false
927+
925928
// Reporters state
926929
private[dotc] var indent: Int = 0
927930

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ object Inliner {
7070
|| (ctx.phase == Phases.typerPhase && needsTransparentInlining(tree))
7171
)
7272
&& !ctx.typer.hasInliningErrors
73+
&& !ctx.base.stopInlining
7374
}
7475

7576
private def needsTransparentInlining(tree: Tree)(using Context): Boolean =
@@ -140,6 +141,7 @@ object Inliner {
140141
val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
141142
new Inliner(tree, body).inlined(tree.srcPos)
142143
else
144+
ctx.base.stopInlining = true
143145
val (reason, setting) =
144146
if reachedInlinedTreesLimit then ("inlined trees", ctx.settings.XmaxInlinedTrees)
145147
else ("successive inlines", ctx.settings.XmaxInlines)
@@ -150,6 +152,10 @@ object Inliner {
150152
|You can use ${setting.name} to change the limit.""",
151153
(tree :: enclosingInlineds).last.srcPos
152154
)
155+
if ctx.base.stopInlining && enclosingInlineds.isEmpty then
156+
ctx.base.stopInlining = false
157+
// we have completely backed out of the call that overflowed;
158+
// reset so that further inline calls can be expanded
153159
tree2
154160
}
155161

tests/neg/i12116.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import compiletime.erasedValue
2+
3+
object test1:
4+
5+
transparent inline def length[T]: Int =
6+
erasedValue[T] match
7+
case _: (h *: t) => 1 + length[t]
8+
case _: EmptyTuple => 0
9+
10+
transparent inline def foo(): Int = 1 + foo()
11+
12+
val y = length[(1, 2, 3)] // error
13+
val x = foo() // error
14+
15+

tests/neg/i12116a.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import compiletime.erasedValue
2+
3+
object test1:
4+
5+
inline def length[T]: Int =
6+
erasedValue[T] match
7+
case _: (h *: t) => 1 + length[t]
8+
case _: EmptyTuple => 0
9+
10+
inline def foo(): Int = 1 + foo()
11+
12+
val y = length[(1, 2, 3)] // error
13+
val x = foo() // error
14+
15+

0 commit comments

Comments
 (0)