diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 1dc6a71fb842..9850076f626e 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -237,6 +237,10 @@ trait QuotesAndSplices { val newSplice = ref(defn.InternalQuoted_exprSplice).appliedToType(tpt1.tpe).appliedTo(Typed(pat, exprTpt)) transform(newSplice) case Apply(TypeApply(fn, targs), Apply(sp, pat :: Nil) :: args :: Nil) if fn.symbol == defn.InternalQuotedMatcher_patternHigherOrderHole => + args match // TODO support these patterns. Possibly using scala.quoted.util.Var + case SeqLiteral(args, _) => + for arg <- args; if arg.symbol.is(Mutable) do + report.error("References to `var`s cannot be used in higher-order pattern", arg.srcPos) try ref(defn.InternalQuotedMatcher_higherOrderHole.termRef).appliedToTypeTrees(targs).appliedTo(args).withSpan(tree.span) finally { val patType = pat.tpe.widen diff --git a/tests/neg-staging/i9692.scala b/tests/neg-staging/i9692.scala new file mode 100644 index 000000000000..fdb4e51bd6bb --- /dev/null +++ b/tests/neg-staging/i9692.scala @@ -0,0 +1,20 @@ +import scala.quoted._ +import scala.quoted.staging._ + +object Test extends App { + + // make available the necessary toolbox for runtime code generation + given Toolbox = Toolbox.make(getClass.getClassLoader) + + run { + val expr: Expr[Int] = '{ var x = 1; x = 2; 42 } + + expr match { + case '{ var x: Int = $binding; $body(x): Int } => // error + val res = Expr.betaReduce('{ $body(4) }) + println(res.show) + res + case _ => println(expr.show); '{0} + } + } +} diff --git a/tests/neg-staging/i9693.scala b/tests/neg-staging/i9693.scala new file mode 100644 index 000000000000..9705bc012c41 --- /dev/null +++ b/tests/neg-staging/i9693.scala @@ -0,0 +1,20 @@ +import scala.quoted._ +import scala.quoted.staging._ + +object Test extends App { + + // make available the necessary toolbox for runtime code generation + given Toolbox = Toolbox.make(getClass.getClassLoader) + + run { + val expr: Expr[Int] = '{ var x = 1; x = 2; 42 } + + expr match { + case '{ var x: Int = $binding; $body(x): Int } => // error + val res = '{ var y = $binding; ${ Expr.betaReduce('{ $body(y) })}} + println(res.show) + res + case _ => println(expr.show); '{0} + } + } +}