diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 0c5aca3c2244..7f47f1696cd6 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1110,6 +1110,11 @@ object SymDenotations { enclClass(symbol, false) } + /** Skips symbol that are not owned by a class */ + def skipLocalOwners(using Context): Symbol = + if symbol.owner.isClass then symbol + else symbol.owner.skipLocalOwners + /** A class that in source code would be lexically enclosing */ final def lexicallyEnclosingClass(using Context): Symbol = if (!exists || isClass) symbol else owner.lexicallyEnclosingClass diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 0d9186a0fb5f..86cd7e5f24f3 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -56,21 +56,23 @@ trait QuotesAndSplices { else if !qctx.tpe.isStable then report.error(em"Quotes require stable Quotes, but found non stable $qctx", qctx.srcPos) - val tree1 = - if ctx.mode.is(Mode.Pattern) then - typedQuotePattern(tree, pt, qctx) - else if tree.quoted.isType then - val msg = em"Consider using canonical type constructor scala.quoted.Type.of[${tree.quoted}] instead" - if sourceVersion.isAtLeast(`future-migration`) then report.error(msg, tree.srcPos) - else report.warning(msg, tree.srcPos) - typedTypeApply(untpd.TypeApply(untpd.ref(defn.QuotedTypeModule_of.termRef), tree.quoted :: Nil), pt)(using quoteContext).select(nme.apply).appliedTo(qctx) - else - typedApply(untpd.Apply(untpd.ref(defn.QuotedRuntime_exprQuote.termRef), tree.quoted), pt)(using pushQuotes(qctx)).select(nme.apply).appliedTo(qctx) - makeInlineable(tree1.withSpan(tree.span)) + if ctx.mode.is(Mode.Pattern) then + typedQuotePattern(tree, pt, qctx).withSpan(tree.span) + else if tree.quoted.isType then + val msg = em"Consider using canonical type constructor scala.quoted.Type.of[${tree.quoted}] instead" + if sourceVersion.isAtLeast(`future-migration`) then report.error(msg, tree.srcPos) + else report.warning(msg, tree.srcPos) + val typeOfTree = untpd.TypeApply(untpd.ref(defn.QuotedTypeModule_of.termRef), tree.quoted :: Nil).withSpan(tree.span) + makeInlineable(typedTypeApply(typeOfTree, pt)(using quoteContext).select(nme.apply).appliedTo(qctx).withSpan(tree.span)) + else + val exprQuoteTree = untpd.Apply(untpd.ref(defn.QuotedRuntime_exprQuote.termRef), tree.quoted) + makeInlineable(typedApply(exprQuoteTree, pt)(using pushQuotes(qctx)).select(nme.apply).appliedTo(qctx).withSpan(tree.span)) } private def makeInlineable(tree: Tree)(using Context): Tree = - PrepareInlineable.makeInlineable(tree) + inContext(ctx.withOwner(ctx.owner.skipLocalOwners)) { + PrepareInlineable.makeInlineable(tree) + } /** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */ def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree = { diff --git a/tests/pos-macros/i13546/Macros_1.scala b/tests/pos-macros/i13546/Macros_1.scala new file mode 100644 index 000000000000..7e90476c5f73 --- /dev/null +++ b/tests/pos-macros/i13546/Macros_1.scala @@ -0,0 +1,13 @@ +package mylib +import scala.quoted.* + +object Main: + protected def foo: Unit = {} + inline def fooCaller: Unit = + def f = foo + foo + inline def fooCallerM: Unit = ${ fooMacro } + def fooMacro(using Quotes): Expr[Unit] = + '{ foo } + val fooExpr = '{ foo } + '{ $fooExpr } diff --git a/tests/pos-macros/i13546/Test_2.scala b/tests/pos-macros/i13546/Test_2.scala new file mode 100644 index 000000000000..386f1b3bd8f5 --- /dev/null +++ b/tests/pos-macros/i13546/Test_2.scala @@ -0,0 +1,5 @@ +import mylib.Main + +object Test: + Main.fooCaller + Main.fooCallerM