diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 60f675ff0b0d..84ba0a452a2e 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -922,6 +922,9 @@ object Contexts { private[core] var denotTransformers: Array[DenotTransformer] = _ + /** Flag to suppress inlining, set after overflow */ + private[dotc] var stopInlining: Boolean = false + // Reporters state private[dotc] var indent: Int = 0 diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 0c0de55daa58..a32a7700f69a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -70,6 +70,7 @@ object Inliner { || (ctx.phase == Phases.typerPhase && needsTransparentInlining(tree)) ) && !ctx.typer.hasInliningErrors + && !ctx.base.stopInlining } private def needsTransparentInlining(tree: Tree)(using Context): Boolean = @@ -140,6 +141,7 @@ object Inliner { val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors new Inliner(tree, body).inlined(tree.srcPos) else + ctx.base.stopInlining = true val (reason, setting) = if reachedInlinedTreesLimit then ("inlined trees", ctx.settings.XmaxInlinedTrees) else ("successive inlines", ctx.settings.XmaxInlines) @@ -150,6 +152,10 @@ object Inliner { |You can use ${setting.name} to change the limit.""", (tree :: enclosingInlineds).last.srcPos ) + if ctx.base.stopInlining && enclosingInlineds.isEmpty then + ctx.base.stopInlining = false + // we have completely backed out of the call that overflowed; + // reset so that further inline calls can be expanded tree2 } diff --git a/tests/neg/i12116.scala b/tests/neg/i12116.scala new file mode 100644 index 000000000000..4f07f4c3db48 --- /dev/null +++ b/tests/neg/i12116.scala @@ -0,0 +1,15 @@ +import compiletime.erasedValue + +object test1: + + transparent inline def length[T]: Int = + erasedValue[T] match + case _: (h *: t) => 1 + length[t] + case _: EmptyTuple => 0 + + transparent inline def foo(): Int = 1 + foo() + + val y = length[(1, 2, 3)] // error + val x = foo() // error + + diff --git a/tests/neg/i12116a.scala b/tests/neg/i12116a.scala new file mode 100644 index 000000000000..4407e42e649b --- /dev/null +++ b/tests/neg/i12116a.scala @@ -0,0 +1,15 @@ +import compiletime.erasedValue + +object test1: + + inline def length[T]: Int = + erasedValue[T] match + case _: (h *: t) => 1 + length[t] + case _: EmptyTuple => 0 + + inline def foo(): Int = 1 + foo() + + val y = length[(1, 2, 3)] // error + val x = foo() // error + +