From 3ac8fd8c710c0543ea2600feab5e05cacb7697f8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 26 Feb 2018 17:30:16 +0100 Subject: [PATCH 1/4] Fix #4023: Ignore healed implicit tag at level 0 --- compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala | 4 +++- tests/pos/i4023/Macro_1.scala | 5 +++++ tests/pos/i4023/Test_2.scala | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i4023/Macro_1.scala create mode 100644 tests/pos/i4023/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index 163c3db800b0..4e067c0752f7 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -77,6 +77,7 @@ class ReifyQuotes extends MacroTransformWithImplicits { */ private class Reifier(inQuote: Boolean, val outer: Reifier, val level: Int, levels: LevelInfo) extends ImplicitsTransformer { import levels._ + assert(level >= 0) /** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */ def nested(isQuote: Boolean): Reifier = @@ -169,7 +170,8 @@ class ReifyQuotes extends MacroTransformWithImplicits { | The access would be accepted with the right type tag, but | ${ctx.typer.missingArgMsg(tag, reqType, "")}""") case _ => - importedTags(tp) = nested(isQuote = false).transform(tag) + if (level > 0) // TODO do we need to find the tag for level 0? + importedTags(tp) = nested(isQuote = false).transform(tag) None } case _ => diff --git a/tests/pos/i4023/Macro_1.scala b/tests/pos/i4023/Macro_1.scala new file mode 100644 index 000000000000..c3c0d2100e14 --- /dev/null +++ b/tests/pos/i4023/Macro_1.scala @@ -0,0 +1,5 @@ +import scala.quoted._ +object Macro { + inline def ff[T: Type](x: T): T = ~impl('(x)) + def impl[T](x: Expr[T]): Expr[T] = x +} \ No newline at end of file diff --git a/tests/pos/i4023/Test_2.scala b/tests/pos/i4023/Test_2.scala new file mode 100644 index 000000000000..73250b37c2c1 --- /dev/null +++ b/tests/pos/i4023/Test_2.scala @@ -0,0 +1,3 @@ +object Test { + Macro.ff(3) +} From dc8920bc1130f31e8d6ba8a3bd11d308eb8fa1f1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 26 Feb 2018 17:39:11 +0100 Subject: [PATCH 2/4] Add test case and fix interpreted TypeApply --- .../src/dotty/tools/dotc/interpreter/Interpreter.scala | 9 ++++----- compiler/src/dotty/tools/dotc/transform/Splicer.scala | 5 +---- tests/pos/i4023b/Macro_1.scala | 5 +++++ tests/pos/i4023b/Test_2.scala | 3 +++ 4 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 tests/pos/i4023b/Macro_1.scala create mode 100644 tests/pos/i4023b/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala index 5be936d71ee1..634c77414bbb 100644 --- a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala @@ -63,11 +63,7 @@ class Interpreter(implicit ctx: Context) { * If some error is encountered while interpreting a ctx.error is emitted and a StopInterpretation is thrown. */ private def interpretTreeImpl(tree: Tree, env: Env): Object = { - ctx.debuglog( - s"""Interpreting: - |${tree.show} - |$env - """.stripMargin) + // println(s"Interpreting:\n${tree.show}\n$env\n") implicit val pos: Position = tree.pos @@ -114,6 +110,9 @@ class Interpreter(implicit ctx: Context) { val env2 = bindings.foldLeft(env)((acc, x) => interpretStat(x, acc)) interpretTreeImpl(expansion, env2) + case TypeApply(fn, _) => + interpretTreeImpl(fn, env) + case Typed(expr, _) => interpretTreeImpl(expr, env) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 2003dba73999..1e71ce697d85 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -16,10 +16,7 @@ object Splicer { */ def splice(tree: Tree)(implicit ctx: Context): Tree = tree match { case Quoted(quotedTree) => quotedTree - case tree: RefTree => reflectiveSplice(tree) - case tree: Apply => reflectiveSplice(tree) - case tree: Inlined => reflectiveSplice(tree) - case tree: Block => reflectiveSplice(tree) + case _ => reflectiveSplice(tree) } /** Splice the Tree for a Quoted expression which is constructed via a reflective call to the given method */ diff --git a/tests/pos/i4023b/Macro_1.scala b/tests/pos/i4023b/Macro_1.scala new file mode 100644 index 000000000000..7aa305e3183a --- /dev/null +++ b/tests/pos/i4023b/Macro_1.scala @@ -0,0 +1,5 @@ +import scala.quoted._ +object Macro { + inline def ff[T](implicit t: Type[T]): Int = ~impl[T] + def impl[T]: Expr[Int] = 4 +} diff --git a/tests/pos/i4023b/Test_2.scala b/tests/pos/i4023b/Test_2.scala new file mode 100644 index 000000000000..4bd71c799fbf --- /dev/null +++ b/tests/pos/i4023b/Test_2.scala @@ -0,0 +1,3 @@ +object Test { + Macro.ff[Int] +} From 3779c8e1ccba3e49d6bf3fa39c34876b6af4c948 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 26 Feb 2018 18:03:38 +0100 Subject: [PATCH 3/4] Fix interpreted type quotes --- compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala | 2 +- tests/pos/macro-with-type/Macro_1.scala | 5 +++++ tests/pos/macro-with-type/Test_2.scala | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/pos/macro-with-type/Macro_1.scala create mode 100644 tests/pos/macro-with-type/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala index 634c77414bbb..0218f7f8b481 100644 --- a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala @@ -69,7 +69,7 @@ class Interpreter(implicit ctx: Context) { tree match { case Quoted(quotedTree) => - if (tree.isTerm) new scala.quoted.Exprs.TreeExpr(quotedTree) + if (quotedTree.isTerm) new scala.quoted.Exprs.TreeExpr(quotedTree) else new scala.quoted.Types.TreeType(quotedTree) case Literal(Constant(c)) => c.asInstanceOf[Object] diff --git a/tests/pos/macro-with-type/Macro_1.scala b/tests/pos/macro-with-type/Macro_1.scala new file mode 100644 index 000000000000..5bf5885b3aa1 --- /dev/null +++ b/tests/pos/macro-with-type/Macro_1.scala @@ -0,0 +1,5 @@ +import scala.quoted._ +object Macro { + inline def ff: Unit = ~impl('[Int]) + def impl(t: Type[Int]): Expr[Unit] = () +} \ No newline at end of file diff --git a/tests/pos/macro-with-type/Test_2.scala b/tests/pos/macro-with-type/Test_2.scala new file mode 100644 index 000000000000..1c6c9b1b8201 --- /dev/null +++ b/tests/pos/macro-with-type/Test_2.scala @@ -0,0 +1,3 @@ +object Test { + Macro.ff +} From 7a5a91e3362dd96a40bce0972e0a5093db8d9f2c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 26 Feb 2018 18:17:16 +0100 Subject: [PATCH 4/4] Fix staged quoted.Type in macro --- .../tools/dotc/transform/ReifyQuotes.scala | 26 +++++++++++-------- tests/pos/i4023c/Macro_1.scala | 5 ++++ tests/pos/i4023c/Test_2.scala | 7 +++++ 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 tests/pos/i4023c/Macro_1.scala create mode 100644 tests/pos/i4023c/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index 4e067c0752f7..adaec52a2917 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -161,18 +161,22 @@ class ReifyQuotes extends MacroTransformWithImplicits { */ def tryHeal(tp: Type, pos: Position)(implicit ctx: Context): Option[String] = tp match { case tp: TypeRef => - val reqType = defn.QuotedTypeType.appliedTo(tp) - val tag = ctx.typer.inferImplicitArg(reqType, pos) - tag.tpe match { - case fail: SearchFailureType => - Some(i""" - | - | The access would be accepted with the right type tag, but - | ${ctx.typer.missingArgMsg(tag, reqType, "")}""") - case _ => - if (level > 0) // TODO do we need to find the tag for level 0? + if (level == 0) { + assert(ctx.owner.is(Macro)) + None + } else { + val reqType = defn.QuotedTypeType.appliedTo(tp) + val tag = ctx.typer.inferImplicitArg(reqType, pos) + tag.tpe match { + case fail: SearchFailureType => + Some(i""" + | + | The access would be accepted with the right type tag, but + | ${ctx.typer.missingArgMsg(tag, reqType, "")}""") + case _ => importedTags(tp) = nested(isQuote = false).transform(tag) - None + None + } } case _ => Some("") diff --git a/tests/pos/i4023c/Macro_1.scala b/tests/pos/i4023c/Macro_1.scala new file mode 100644 index 000000000000..7e5714514b8d --- /dev/null +++ b/tests/pos/i4023c/Macro_1.scala @@ -0,0 +1,5 @@ +import scala.quoted._ +object Macro { + inline def ff[T](x: T): T = ~impl('(x), '[T]) + def impl[T](x: Expr[T], t: Type[T]): Expr[T] = '{ (~x): ~t } +} diff --git a/tests/pos/i4023c/Test_2.scala b/tests/pos/i4023c/Test_2.scala new file mode 100644 index 000000000000..512a2ab27495 --- /dev/null +++ b/tests/pos/i4023c/Test_2.scala @@ -0,0 +1,7 @@ +object Test { + Macro.ff(3) + + def f[T](x: T) = { + Macro.ff(x) + } +}