diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 1d1c2db683b7..67db036ee4ff 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -240,8 +240,15 @@ trait QuotesAndSplices { TypeTree(tree.tpe.dealias).withSpan(tree.span) else tree - case tdef: TypeDef if tdef.symbol.hasAnnotation(defn.InternalQuoted_patternTypeAnnot) => - transformTypeBindingTypeDef(tdef, typePatBuf) + case tdef: TypeDef => + if tdef.symbol.hasAnnotation(defn.InternalQuoted_patternTypeAnnot) then + transformTypeBindingTypeDef(tdef, typePatBuf) + else if tdef.symbol.isClass then + val kind = if tdef.symbol.is(Module) then "objects" else "classes" + ctx.error("Implementation restriction: cannot match " + kind, tree.sourcePos) + EmptyTree + else + super.transform(tree) case tree @ AppliedTypeTree(tpt, args) => val args1: List[Tree] = args.zipWithConserve(tpt.tpe.typeParams.map(_.paramVarianceSign)) { (arg, v) => arg.tpe match { @@ -254,6 +261,15 @@ trait QuotesAndSplices { if tree.name.isTermName && !tree.nameSpan.isSynthetic && tree.name.startsWith("$") then ctx.error("Names cannot start with $ quote pattern ", tree.namePos) super.transform(tree) + case _: Match => + ctx.error("Implementation restriction: cannot match `match` expressions", tree.sourcePos) + EmptyTree + case _: Try => + ctx.error("Implementation restriction: cannot match `try` expressions", tree.sourcePos) + EmptyTree + case _: Return => + ctx.error("Implementation restriction: cannot match `return` statements", tree.sourcePos) + EmptyTree case _ => super.transform(tree) } diff --git a/tests/neg-macros/quote-pattern-implemnetation-restrictions.scala b/tests/neg-macros/quote-pattern-implemnetation-restrictions.scala new file mode 100644 index 000000000000..2138c02d6fa4 --- /dev/null +++ b/tests/neg-macros/quote-pattern-implemnetation-restrictions.scala @@ -0,0 +1,12 @@ +import scala.quoted._ + +def f(x: Expr[Any])(using QuoteContext) = + x match { + case '{ class Foo; () } => // error + case '{ object Foo; () } => // error + case '{ 1 match { case _ => () } } => // error + case '{ try 1 finally () } => // error + case '{ try 1 catch { case _ => 4 } } => // error + case '{ Nil.map({ case x: Int => () }) } => // error + case '{ def f: Int = return 2 } => // error + } diff --git a/tests/pos/quoted-pattern-type.scala b/tests/pos/quoted-pattern-type.scala index 5fdffbf35d07..9b6c06601bb3 100644 --- a/tests/pos/quoted-pattern-type.scala +++ b/tests/pos/quoted-pattern-type.scala @@ -42,22 +42,6 @@ object Lib { z: Expr[T & Int] e - case e @ '{ ($x: Boolean) match { case _ => $y: Int } } => - e: Expr[T & Int] - y: Expr[T & Int] - e - - case e @ '{ ($x: Boolean) match { case _ => $y } } => - e: Expr[T] - y: Expr[T] - e - - case e @ '{ try ($x: Boolean) catch { case _ => $y: Int } } => - e: Expr[T & (Boolean | Int)] - x: Expr[T & Boolean] - y: Expr[T & Int] - e - } } }