From 15cff7c0b144332fdfcf8b02c7bb953f616ff3d7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 17:38:13 +0200 Subject: [PATCH 1/3] Fix #4493: Use captured macro type parameters refrences --- compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala | 7 ++++++- tests/pos/i4493-b.scala | 7 +++++++ tests/pos/i4493-c.scala | 6 ++++++ tests/pos/i4493.scala | 7 +++++++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i4493-b.scala create mode 100644 tests/pos/i4493-c.scala create mode 100644 tests/pos/i4493.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index e854231d1e05..ee31ba491544 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]) + } +} From 779fc662ae6f175d507b59a79d2a51b19ac75717 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 18:22:52 +0200 Subject: [PATCH 2/3] Fix #4514: Add regression test --- tests/pos/i4514.scala | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/pos/i4514.scala 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] = '() +} From 2e04698cb0da9e6471149d107c1955d137232efa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 17 May 2018 14:09:50 +0200 Subject: [PATCH 3/3] Fix typo in method name It was supposed to be `isNotRoot`, now it is actually `isRoot` --- compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index ee31ba491544..c5951fd10432 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -145,7 +145,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { def inSplice = outer != null && !inQuote /** We are not in a `~(...)` or a `'(...)` */ - def isRoot = outer != null + 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 @@ -294,7 +294,7 @@ 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) + 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))