From ecee4985ae982612232d84235553978ccbdbe105 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sun, 8 Mar 2020 17:57:52 +0100 Subject: [PATCH] Fix #7698: Disallow quoted patterns against non Expr/Type --- .../dotty/tools/dotc/typer/QuotesAndSplices.scala | 5 +++++ tests/neg/i7698.scala | 14 ++++++++++++++ tests/pos/i6998.scala | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i7698.scala diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index e813b87c978f..92e3e4ef188a 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -337,6 +337,11 @@ trait QuotesAndSplices { * ``` */ private def typedQuotePattern(tree: untpd.Quote, pt: Type, qctx: Tree)(implicit ctx: Context): Tree = { + if tree.quoted.isTerm && !pt.derivesFrom(defn.QuotedExprClass) then + ctx.error("Quote pattern can only match scrutinees of type scala.quoted.Expr", tree.sourcePos) + else if tree.quoted.isType && !pt.derivesFrom(defn.QuotedTypeClass) then + ctx.error("Quote pattern can only match scrutinees of type scala.quoted.Type", tree.sourcePos) + val quoted = tree.quoted val exprPt = pt.baseType(if quoted.isType then defn.QuotedTypeClass else defn.QuotedExprClass) val quotedPt = exprPt.argInfos.headOption match { diff --git a/tests/neg/i7698.scala b/tests/neg/i7698.scala new file mode 100644 index 000000000000..a71b53a6267e --- /dev/null +++ b/tests/neg/i7698.scala @@ -0,0 +1,14 @@ +import scala.quoted._ +import scala.quoted.matching._ + +trait Show[T] { + def show(x: T): String +} + +def showInterpolatorImpl(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = + argsExpr.unseal match + case '{ $arg: $t } => // error + case '[ Int ] => // error + ??? + +inline def (sc: => StringContext) show (args: Any*): String = ${ showInterpolatorImpl('sc, 'args) } diff --git a/tests/pos/i6998.scala b/tests/pos/i6998.scala index e87f45166368..41b34d785c23 100644 --- a/tests/pos/i6998.scala +++ b/tests/pos/i6998.scala @@ -1,5 +1,5 @@ import scala.quoted._ def foo(using QuoteContext) : Unit = { - val '{ $f : (Int => Double) } = ??? + val '{ $f : (Int => Double) } = ??? : Expr[Any] }