From 6e20e72161ea5546274f64c9c094540eab571a17 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 7 Aug 2019 12:58:11 +0200 Subject: [PATCH 1/2] Fix #6997: Adapt quote type direct aliase to type splice --- .../tools/dotc/transform/PCPCheckAndHeal.scala | 4 ++++ tests/pos/i6997.scala | 8 ++++++++ tests/pos/i6997b.scala | 15 +++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 tests/pos/i6997.scala create mode 100644 tests/pos/i6997b.scala diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 5f1c769ccb6a..b12c3a138891 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -112,6 +112,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( if (tp.isTerm) ctx.error(i"splice outside quotes", pos) tp + case tp: TypeRef if tp.prefix.derivesFrom(defn.QuotedTypeClass) && tp.name.toString == "T" => + // Adapt direct references to the type of the type parameter T of a quoted.Type[T]. + // Replace it with a properly encoded type splice. This is the normal for expected for type splices. + tp.prefix.select(tpnme.splice) case tp: NamedType => checkSymLevel(tp.symbol, tp, pos) match { case Some(tpRef) => tpRef.tpe diff --git a/tests/pos/i6997.scala b/tests/pos/i6997.scala new file mode 100644 index 000000000000..2ac86b1def07 --- /dev/null +++ b/tests/pos/i6997.scala @@ -0,0 +1,8 @@ + +import scala.quoted._ +class Foo { + def mcrImpl(body: Expr[Any]) given (t: Type[_ <: Any]) given (ctx: QuoteContext): Expr[Any] = '{ + val tmp = ???.asInstanceOf[$t] + tmp + } +} diff --git a/tests/pos/i6997b.scala b/tests/pos/i6997b.scala new file mode 100644 index 000000000000..7b49aef3b2a4 --- /dev/null +++ b/tests/pos/i6997b.scala @@ -0,0 +1,15 @@ +package playground + +import scala.quoted._, scala.quoted.matching._ +import delegate scala.quoted._ + +inline def mcr(x: => Any): Any = ${mcrImpl('x)} + +def mcrImpl(body: Expr[Any]) given (ctx: QuoteContext): Expr[Any] = { + val '{$x: $t} = body + '{ + val tmp: $t = $x.asInstanceOf[$t] + println(tmp) + tmp + } +} \ No newline at end of file From 29a551b479f2329c609dffb0a5a2529b6b7e265b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 19 Aug 2019 14:24:44 +0200 Subject: [PATCH 2/2] Get type parameter symbol through class definition --- compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index b12c3a138891..62956dde81c6 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -112,7 +112,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( if (tp.isTerm) ctx.error(i"splice outside quotes", pos) tp - case tp: TypeRef if tp.prefix.derivesFrom(defn.QuotedTypeClass) && tp.name.toString == "T" => + case tp: TypeRef if tp.symbol == defn.QuotedTypeClass.typeParams.head => // Adapt direct references to the type of the type parameter T of a quoted.Type[T]. // Replace it with a properly encoded type splice. This is the normal for expected for type splices. tp.prefix.select(tpnme.splice)