From 13731926a788ce747720106c9935724c9e8bf75a Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 26 Sep 2024 16:14:47 +0200 Subject: [PATCH] Handle suspension due to macro call in late phases In the added test case this happens in PostTyper, but I've seen it happen in Mixin too. Fixes #18517. --- compiler/src/dotty/tools/dotc/core/Phases.scala | 14 +++++++++----- .../dotty/tools/dotc/transform/Inlining.scala | 8 +------- tests/pos-macros/i18517/Caller.scala | 17 +++++++++++++++++ tests/pos-macros/i18517/Macro.scala | 7 +++++++ tests/pos-macros/i18517/User.scala | 6 ++++++ 5 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 tests/pos-macros/i18517/Caller.scala create mode 100644 tests/pos-macros/i18517/Macro.scala create mode 100644 tests/pos-macros/i18517/User.scala diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala index 5dff95fc51fb..85df3f9f2c18 100644 --- a/compiler/src/dotty/tools/dotc/core/Phases.scala +++ b/compiler/src/dotty/tools/dotc/core/Phases.scala @@ -378,14 +378,18 @@ object Phases { () else run - catch case ex: Throwable if !ctx.run.enrichedErrorMessage => - println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit")) - throw ex + buf += unitCtx.compilationUnit + catch + case _: CompilationUnit.SuspendException => // this unit will be run again in `Run#compileSuspendedUnits` + case ex: Throwable if !ctx.run.enrichedErrorMessage => + println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit")) + throw ex finally ctx.run.advanceUnit() - buf += unitCtx.compilationUnit end if end for - buf.result() + val res = buf.result() + ctx.run.nn.checkSuspendedUnits(res) + res end runOn /** Convert a compilation unit's tree to a string; can be overridden */ diff --git a/compiler/src/dotty/tools/dotc/transform/Inlining.scala b/compiler/src/dotty/tools/dotc/transform/Inlining.scala index 335d5a38931a..751636c7d806 100644 --- a/compiler/src/dotty/tools/dotc/transform/Inlining.scala +++ b/compiler/src/dotty/tools/dotc/transform/Inlining.scala @@ -36,13 +36,7 @@ class Inlining extends MacroTransform, IdentityDenotTransformer { override def run(using Context): Unit = if ctx.compilationUnit.needsInlining || ctx.compilationUnit.hasMacroAnnotations then - try super.run - catch case _: CompilationUnit.SuspendException => () - - override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] = - val newUnits = super.runOn(units).filterNot(_.suspended) - ctx.run.nn.checkSuspendedUnits(newUnits) - newUnits + super.run override def checkPostCondition(tree: Tree)(using Context): Unit = tree match { diff --git a/tests/pos-macros/i18517/Caller.scala b/tests/pos-macros/i18517/Caller.scala new file mode 100644 index 000000000000..71d965788e22 --- /dev/null +++ b/tests/pos-macros/i18517/Caller.scala @@ -0,0 +1,17 @@ +package dummy + +trait BG { + val description: { type Structure } + type Structure = description.Structure +} + +abstract class Caller extends BG { + type Foo >: this.type <: this.type + + transparent inline def generate2() = + ${Macro.impl() } + + final val description = { + generate2() + } +} diff --git a/tests/pos-macros/i18517/Macro.scala b/tests/pos-macros/i18517/Macro.scala new file mode 100644 index 000000000000..500075f54c47 --- /dev/null +++ b/tests/pos-macros/i18517/Macro.scala @@ -0,0 +1,7 @@ +package dummy + +import scala.quoted.* + +object Macro: + def impl()(using quotes:Quotes) : Expr[Any] = + '{ null } diff --git a/tests/pos-macros/i18517/User.scala b/tests/pos-macros/i18517/User.scala new file mode 100644 index 000000000000..8216c581937b --- /dev/null +++ b/tests/pos-macros/i18517/User.scala @@ -0,0 +1,6 @@ +package dummy + +trait User: + final def bar(cell:Any) : Unit = + (cell: cell.type) match + case c: (Caller & cell.type) => ()