From 71f9a9fded4be902221ab73437dd6678d2287ef7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 24 Aug 2023 16:27:04 +0200 Subject: [PATCH] Fix macro dependency tracking for `this` The symbols of trees do not have enough information to determine the full dependencies. For example, if we have an `Ident` we need to look at its type to figure out which is the `this` prefix on which it is defined. Fix #18434 --- .../dotty/tools/dotc/inlines/Inliner.scala | 20 +++++++++++++------ tests/pos-macros/i18434/Inline_2.scala | 8 ++++++++ tests/pos-macros/i18434/Macro_1.scala | 7 +++++++ tests/pos-macros/i18434/Test_2.scala | 5 +++++ 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 tests/pos-macros/i18434/Inline_2.scala create mode 100644 tests/pos-macros/i18434/Macro_1.scala create mode 100644 tests/pos-macros/i18434/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala index 8bd89a71fa50..9703332f9e61 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala @@ -1065,15 +1065,23 @@ class Inliner(val call: tpd.Tree)(using Context): * This corresponds to the symbols that will need to be interpreted. */ private def macroDependencies(tree: Tree)(using Context) = + val typeAccumulator = new TypeAccumulator[List[Symbol]] { + def apply(x: List[Symbol], tp: Type): List[Symbol] = tp match + case tp: TermRef => + if tp.symbol.isDefinedInCurrentRun then foldOver(tp.symbol :: x, tp) + else foldOver(x, tp) + case tp: ThisType if tp.typeSymbol.isDefinedInCurrentRun => + foldOver(tp.typeSymbol :: x, tp) + case _ => + x + } new TreeAccumulator[List[Symbol]] { override def apply(syms: List[Symbol], tree: tpd.Tree)(using Context): List[Symbol] = - tree match { - case tree: RefTree if tree.isTerm && level == -1 && tree.symbol.isDefinedInCurrentRun && !tree.symbol.isLocal => - foldOver(tree.symbol :: syms, tree) - case _: This if level == -1 && tree.symbol.isDefinedInCurrentRun => - tree.symbol :: syms + tree match + case tree: RefTree if tree.isTerm && level == -1 && !tree.symbol.isLocal => + typeAccumulator(syms, tree.tpe) case _: TypTree => syms case _ => foldOver(syms, tree) - } }.apply(Nil, tree) + end Inliner diff --git a/tests/pos-macros/i18434/Inline_2.scala b/tests/pos-macros/i18434/Inline_2.scala new file mode 100644 index 000000000000..6818df6b81e3 --- /dev/null +++ b/tests/pos-macros/i18434/Inline_2.scala @@ -0,0 +1,8 @@ +package user + +import defn.Macro + +object Inline extends Macro { + inline def callMacro(): Int = + ${ impl() } +} diff --git a/tests/pos-macros/i18434/Macro_1.scala b/tests/pos-macros/i18434/Macro_1.scala new file mode 100644 index 000000000000..fe99162bdf84 --- /dev/null +++ b/tests/pos-macros/i18434/Macro_1.scala @@ -0,0 +1,7 @@ +package defn + +import scala.quoted.* + +abstract class Macro { + def impl()(using Quotes): Expr[Int] = '{1} +} diff --git a/tests/pos-macros/i18434/Test_2.scala b/tests/pos-macros/i18434/Test_2.scala new file mode 100644 index 000000000000..666bf5fd379f --- /dev/null +++ b/tests/pos-macros/i18434/Test_2.scala @@ -0,0 +1,5 @@ +package user + +object Test { + Inline.callMacro() +}