From ebf5b96bfffe1659bdb28fd66e501becd3102cf2 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 4 May 2020 09:20:36 +0200 Subject: [PATCH 1/2] Fix #8871: Detect explicit splices of quoted.Type[?] --- .../src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala | 4 ++++ tests/{pos => neg}/i6997.scala | 2 +- tests/neg/i8871.scala | 8 ++++++++ tests/neg/i8871b.scala | 9 +++++++++ tests/pos-macros/tasty-constant-type/Macro_1.scala | 5 ++--- 5 files changed, 24 insertions(+), 4 deletions(-) rename tests/{pos => neg}/i6997.scala (73%) create mode 100644 tests/neg/i8871.scala create mode 100644 tests/neg/i8871b.scala diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 7e4ee3c3dbb9..cf77d8e1ff51 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -177,6 +177,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( case prefix: ThisType if !tp.symbol.isStatic && level > levelOf(prefix.cls) => tryHeal(tp.symbol, tp, pos) case prefix: TermRef if tp.symbol.isSplice => + prefix.symbol.info.argInfos match + case (tb: TypeBounds) :: _ => + ctx.error(em"Cannot splice $tp with wildcard type", pos) + case _ => // Heal explicit type splice in the code if level > 0 then getQuoteTypeTags.getTagRef(prefix) else tp case prefix: TermRef if !prefix.symbol.isStatic && level > levelOf(prefix.symbol) => diff --git a/tests/pos/i6997.scala b/tests/neg/i6997.scala similarity index 73% rename from tests/pos/i6997.scala rename to tests/neg/i6997.scala index fb8f8e6d1aa4..c90239ef986a 100644 --- a/tests/pos/i6997.scala +++ b/tests/neg/i6997.scala @@ -2,7 +2,7 @@ import scala.quoted._ class Foo { def mcrImpl(body: Expr[Any])(using t: Type[_ <: Any])(using ctx: QuoteContext): Expr[Any] = '{ - val tmp = ???.asInstanceOf[$t] + val tmp = ???.asInstanceOf[$t] // error // error tmp } } diff --git a/tests/neg/i8871.scala b/tests/neg/i8871.scala new file mode 100644 index 000000000000..4fa1bd3af936 --- /dev/null +++ b/tests/neg/i8871.scala @@ -0,0 +1,8 @@ +import scala.quoted._ +object Macro { + def impl[A : Type](using qctx: QuoteContext): Unit = { + import qctx.tasty._ + val tpe = typeOf[A].seal.asInstanceOf[quoted.Type[_ <: AnyRef]] + '{ (a: ${tpe}) => ???} // error + } +} diff --git a/tests/neg/i8871b.scala b/tests/neg/i8871b.scala new file mode 100644 index 000000000000..bb363e90f29e --- /dev/null +++ b/tests/neg/i8871b.scala @@ -0,0 +1,9 @@ +import scala.quoted._ +object Macro { + def impl[A : Type](using qctx: QuoteContext): Unit = { + import qctx.tasty._ + val tpe/*: quoted.Type[? <: AnyKind]*/ = typeOf[A].seal + '{ f[$tpe] } // error + } + def f[T <: AnyKind]: Unit = () +} diff --git a/tests/pos-macros/tasty-constant-type/Macro_1.scala b/tests/pos-macros/tasty-constant-type/Macro_1.scala index ee564610f299..effb2252a56b 100644 --- a/tests/pos-macros/tasty-constant-type/Macro_1.scala +++ b/tests/pos-macros/tasty-constant-type/Macro_1.scala @@ -12,8 +12,7 @@ object Macro { val ConstantType(Constant(v1: Int)) = a.unseal.tpe val ConstantType(Constant(v2: Int)) = b.unseal.tpe - val t = Literal(Constant((v1 + v2): Int)).tpe.seal - - '{ null: AddInt[$a, $b] { type Out = $t } } + Literal(Constant((v1 + v2): Int)).tpe.seal match + case '[$t] => '{ null: AddInt[$a, $b] { type Out = $t } } } } From 09152eb203fc3488e86e6591628a7fd2d73e762a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 May 2020 15:39:18 +0200 Subject: [PATCH 2/2] Update compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala Co-authored-by: Fengyun Liu --- 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 cf77d8e1ff51..4300139c1f1b 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -179,7 +179,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( case prefix: TermRef if tp.symbol.isSplice => prefix.symbol.info.argInfos match case (tb: TypeBounds) :: _ => - ctx.error(em"Cannot splice $tp with wildcard type", pos) + ctx.error(em"Cannot splice $tp because it is a wildcard type", pos) case _ => // Heal explicit type splice in the code if level > 0 then getQuoteTypeTags.getTagRef(prefix) else tp