diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index e854231d1e05..c5951fd10432 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -120,7 +120,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { * * See `isCaptured` */ - val capturers = new mutable.HashMap[Symbol, RefTree => Tree] + val capturers = new mutable.HashMap[Symbol, Tree => Tree] } /** The main transformer class @@ -144,6 +144,9 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { /** We are in a `~(...)` context that is not shadowed by a nested `'(...)` */ def inSplice = outer != null && !inQuote + /** We are not in a `~(...)` or a `'(...)` */ + def isRoot = outer == null + /** A map from type ref T to expressions of type `quoted.Type[T]`". * These will be turned into splices using `addTags` and represent type variables * that can be possibly healed. @@ -291,6 +294,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { else i"${sym.name}.this" if (!isThis && sym.maybeOwner.isType && !sym.is(Param)) check(sym.owner, sym.owner.thisType, pos) + else if (level == 1 && sym.isType && sym.is(Param) && sym.owner.is(Macro) && !outer.isRoot) + importedTags(sym.typeRef) = capturers(sym)(ref(sym)) else if (sym.exists && !sym.isStaticOwner && !levelOK(sym)) for (errMsg <- tryHeal(tp, pos)) ctx.error(em"""access to $symStr from wrong staging level: diff --git a/tests/pos/i4493-b.scala b/tests/pos/i4493-b.scala new file mode 100644 index 000000000000..fdc3b6cf7867 --- /dev/null +++ b/tests/pos/i4493-b.scala @@ -0,0 +1,7 @@ +class Index[K] +object Index { + inline def succ[K](x: K): Unit = ~{ + implicit val t: quoted.Type[K] = '[K] + '(new Index[K]) + } +} diff --git a/tests/pos/i4493-c.scala b/tests/pos/i4493-c.scala new file mode 100644 index 000000000000..08327e5fa81a --- /dev/null +++ b/tests/pos/i4493-c.scala @@ -0,0 +1,6 @@ +class Index[K] +object Index { + inline def succ[K]: Unit = ~{ + '(new Index[K]) + } +} diff --git a/tests/pos/i4493.scala b/tests/pos/i4493.scala new file mode 100644 index 000000000000..4d125d31ec6e --- /dev/null +++ b/tests/pos/i4493.scala @@ -0,0 +1,7 @@ +class Index[K] +object Index { + inline def succ[K]: Unit = ~{ + implicit val t: quoted.Type[K] = '[K] + '(new Index[K]) + } +} diff --git a/tests/pos/i4514.scala b/tests/pos/i4514.scala new file mode 100644 index 000000000000..0da1e9af33f7 --- /dev/null +++ b/tests/pos/i4514.scala @@ -0,0 +1,4 @@ +object Foo { + inline def foo[X](x: X): Unit = ~fooImpl('(x)) + def fooImpl[X: quoted.Type](x: X): quoted.Expr[Unit] = '() +}