diff --git a/compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala b/compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala index 76961f691617..1ebf2ae5714b 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala @@ -28,7 +28,9 @@ object QuotePatterns: /** Check for restricted patterns */ def checkPattern(quotePattern: QuotePattern)(using Context): Unit = new tpd.TreeTraverser { def traverse(tree: Tree)(using Context): Unit = tree match { - case _: SplicePattern => + case tree: SplicePattern => + if !tree.body.typeOpt.derivesFrom(defn.QuotedExprClass) then + report.error(i"Splice pattern must match an Expr[...]", tree.body.srcPos) case tdef: TypeDef if tdef.symbol.isClass => val kind = if tdef.symbol.is(Module) then "objects" else "classes" report.error(em"Implementation restriction: cannot match $kind", tree.srcPos) diff --git a/tests/neg-macros/i19941.check b/tests/neg-macros/i19941.check new file mode 100644 index 000000000000..6d39e2bef4d8 --- /dev/null +++ b/tests/neg-macros/i19941.check @@ -0,0 +1,4 @@ +-- Error: tests/neg-macros/i19941.scala:7:14 --------------------------------------------------------------------------- +7 | case '{ ${hd *: tl} : *:[Int, EmptyTuple] } => '{ ??? } // error + | ^^^^^^^^ + | Splice pattern must match an Expr[...] diff --git a/tests/neg-macros/i19941.scala b/tests/neg-macros/i19941.scala new file mode 100644 index 000000000000..58a2275d055b --- /dev/null +++ b/tests/neg-macros/i19941.scala @@ -0,0 +1,7 @@ +import scala.quoted.* + +inline def expandMacro(inline from: Tuple): Any = ${ expandMacroImpl } + +def expandMacroImpl(using Quotes): Expr[?] = + '{ 1 *: EmptyTuple } match + case '{ ${hd *: tl} : *:[Int, EmptyTuple] } => '{ ??? } // error diff --git a/tests/pos-macros/quotedPatterns-4.scala b/tests/neg-macros/quotedPatterns-4.scala similarity index 64% rename from tests/pos-macros/quotedPatterns-4.scala rename to tests/neg-macros/quotedPatterns-4.scala index 309b026e3d54..811196bc3a3b 100644 --- a/tests/pos-macros/quotedPatterns-4.scala +++ b/tests/neg-macros/quotedPatterns-4.scala @@ -3,7 +3,7 @@ object Test { def impl(receiver: Expr[StringContext])(using qctx: scala.quoted.Quotes) = { import quotes.reflect.Repeated receiver match { - case '{ StringContext(${Repeated(parts, tpt)}*) } => // now OK + case '{ StringContext(${Repeated(parts, tpt)}*) } => // error: Repeated is not an Expr pattern } } }