From d0b02b72f833bc83cf6f598897c8fe3f4ba1e1f2 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 completed in arbitrary phases Previously we only supported suspension in Typer and Inliner. 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..3f5ce9eee903 --- /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..d18b07e910a5 --- /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) => ()