From ecb82174cf9d95d4f416a48fca0fc319a59ad68e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 16 Aug 2019 09:34:29 +0200 Subject: [PATCH 1/4] Fix #7052: Transform annotations in ReifyQuotes --- .../src/dotty/tools/dotc/transform/ReifyQuotes.scala | 11 ++++++++++- compiler/test/dotc/pos-from-tasty.blacklist | 1 + tests/pos/i7052.scala | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i7052.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index d042966bdc30..72d66c5ea9e6 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -19,7 +19,7 @@ import dotty.tools.dotc.ast.tpd import typer.Implicits.SearchFailureType import scala.collection.mutable -import dotty.tools.dotc.core.Annotations.Annotation +import dotty.tools.dotc.core.Annotations._ import dotty.tools.dotc.core.Names._ import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.quoted._ @@ -405,6 +405,15 @@ class ReifyQuotes extends MacroTransform { // TODO move to FirstTransform to trigger even without quotes cpy.DefDef(tree)(rhs = defaultValue(tree.rhs.tpe)) + case tree: DefTree if level >= 1 => + val newAnnotations = tree.symbol.annotations.mapconserve { + case ConcreteAnnotation(annotTree) => + val newAnnotTree = transform(annotTree) given ctx.withOwner(tree.symbol) + ConcreteAnnotation(newAnnotTree) + case annot => annot + } + tree.symbol.annotations = newAnnotations + super.transform(tree) case _ => super.transform(tree) } diff --git a/compiler/test/dotc/pos-from-tasty.blacklist b/compiler/test/dotc/pos-from-tasty.blacklist index 1c1b2e32e86c..ae7ebcfa0ecc 100644 --- a/compiler/test/dotc/pos-from-tasty.blacklist +++ b/compiler/test/dotc/pos-from-tasty.blacklist @@ -6,3 +6,4 @@ t3612.scala # Other failure t802.scala +i7052.scala diff --git a/tests/pos/i7052.scala b/tests/pos/i7052.scala new file mode 100644 index 000000000000..765a03c4fe1e --- /dev/null +++ b/tests/pos/i7052.scala @@ -0,0 +1,7 @@ +import scala.quoted._ +class Test { + def foo(str: Expr[String]) given QuoteContext = '{ + @deprecated($str, "") + def bar = ??? + } +} From b47498ded58041fd0609eeb2972316f1a2012adb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 19 Aug 2019 11:58:41 +0200 Subject: [PATCH 2/4] Handle annon annotations that have splices --- .../src/dotty/tools/dotc/transform/ReifyQuotes.scala | 9 ++++----- compiler/test/dotc/pos-from-tasty.blacklist | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index 72d66c5ea9e6..1fcf51858e9a 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -406,11 +406,10 @@ class ReifyQuotes extends MacroTransform { cpy.DefDef(tree)(rhs = defaultValue(tree.rhs.tpe)) case tree: DefTree if level >= 1 => - val newAnnotations = tree.symbol.annotations.mapconserve { - case ConcreteAnnotation(annotTree) => - val newAnnotTree = transform(annotTree) given ctx.withOwner(tree.symbol) - ConcreteAnnotation(newAnnotTree) - case annot => annot + val newAnnotations = tree.symbol.annotations.mapconserve { annot => + val newAnnotTree = transform(annot.tree) given ctx.withOwner(tree.symbol) + if (annot.tree == newAnnotTree) annot + else ConcreteAnnotation(newAnnotTree) } tree.symbol.annotations = newAnnotations super.transform(tree) diff --git a/compiler/test/dotc/pos-from-tasty.blacklist b/compiler/test/dotc/pos-from-tasty.blacklist index ae7ebcfa0ecc..1c1b2e32e86c 100644 --- a/compiler/test/dotc/pos-from-tasty.blacklist +++ b/compiler/test/dotc/pos-from-tasty.blacklist @@ -6,4 +6,3 @@ t3612.scala # Other failure t802.scala -i7052.scala From c13fac875b914e91e6559387b469779a993d4c82 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 19 Aug 2019 13:18:50 +0200 Subject: [PATCH 3/4] Check PCP in annotations --- .../src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala | 4 ++-- .../src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala | 4 ++++ tests/neg/i7052.scala | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i7052.scala diff --git a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala index 2e03b44c3b1d..154729a877c8 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala @@ -62,7 +62,7 @@ class TreeMapWithImplicits extends tpd.TreeMap { private def nestedScopeCtx(defs: List[Tree])(implicit ctx: Context): Context = { val nestedCtx = ctx.fresh.setNewScope defs foreach { - case d: DefTree => nestedCtx.enter(d.symbol) + case d: DefTree if d.symbol.isOneOf(GivenOrImplicit) => nestedCtx.enter(d.symbol) case _ => } nestedCtx @@ -73,7 +73,7 @@ class TreeMapWithImplicits extends tpd.TreeMap { new TreeTraverser { def traverse(tree: Tree)(implicit ctx: Context): Unit = { tree match { - case d: DefTree => nestedCtx.enter(d.symbol) + case d: DefTree if d.symbol.isOneOf(GivenOrImplicit) => nestedCtx.enter(d.symbol) case _ => } traverseChildren(tree) diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 90c68d8e5b75..f5951bf12118 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -38,6 +38,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( transform(tree)(ctx.withSource(tree.source)) else tree match { case tree: DefDef if tree.symbol.is(Inline) && level > 0 => EmptyTree + case tree: DefTree => + for (annot <- tree.symbol.annotations) + transform(annot.tree) given ctx.withOwner(tree.symbol) + checkLevel(super.transform(tree)) case _ => checkLevel(super.transform(tree)) } } diff --git a/tests/neg/i7052.scala b/tests/neg/i7052.scala new file mode 100644 index 000000000000..3c6f932c3bf7 --- /dev/null +++ b/tests/neg/i7052.scala @@ -0,0 +1,7 @@ +import scala.quoted._ +class Test { + def foo(str: String) given QuoteContext = '{ + @deprecated(str, "") // error + def bar = ??? + } +} From 866d6abd5f6947c6bffd3b53aeabdcb2a44a63a2 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 21 Aug 2019 13:32:05 +0200 Subject: [PATCH 4/4] Add regression test --- tests/neg/i7052b.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/neg/i7052b.scala diff --git a/tests/neg/i7052b.scala b/tests/neg/i7052b.scala new file mode 100644 index 000000000000..d5ef75aa7a79 --- /dev/null +++ b/tests/neg/i7052b.scala @@ -0,0 +1,10 @@ +import scala.quoted._ +class Test { + def foo(str: String) given QuoteContext = '{ + delegate for QuoteContext = ??? + '{ + @deprecated(str, "") // error + def bar = ??? + } + } +}