diff --git a/compiler/src/dotty/tools/dotc/core/Mode.scala b/compiler/src/dotty/tools/dotc/core/Mode.scala index ec8ab0dbca15..d141cf7032ee 100644 --- a/compiler/src/dotty/tools/dotc/core/Mode.scala +++ b/compiler/src/dotty/tools/dotc/core/Mode.scala @@ -89,7 +89,7 @@ object Mode { /** Don't suppress exceptions thrown during show */ val PrintShowExceptions: Mode = newMode(18, "PrintShowExceptions") - val PatternOrTypeBits: Mode = Pattern | Type | InPatternAlternative + val PatternOrTypeBits: Mode = Pattern | Type /** We are elaborating the fully qualified name of a package clause. * In this case, identifiers should never be imported. diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 4a9102df211d..5f14352a1fb3 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -20,7 +20,7 @@ import dotty.tools.dotc.typer.Implicits._ import dotty.tools.dotc.typer.Inferencing._ import dotty.tools.dotc.util.Spans._ import dotty.tools.dotc.util.Stats.record - +import dotty.tools.dotc.reporting.IllegalVariableInPatternAlternative import scala.collection.mutable @@ -321,7 +321,9 @@ trait QuotesAndSplices { } private def transformTypeBindingTypeDef(nameOfSyntheticGiven: TermName, tdef: TypeDef, buff: mutable.Builder[Tree, List[Tree]])(using Context): Tree = { - if (variance == -1) + if ctx.mode.is(Mode.InPatternAlternative) then + report.error(IllegalVariableInPatternAlternative(tdef.symbol.name), tdef.srcPos) + if variance == -1 then tdef.symbol.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_fromAboveAnnot.typeRef)).withSpan(tdef.span))) val bindingType = getBinding(tdef.symbol).symbol.typeRef val bindingTypeTpe = AppliedType(defn.QuotedTypeClass.typeRef, bindingType :: Nil) diff --git a/tests/neg-macros/i14696.scala b/tests/neg-macros/i14696.scala new file mode 100644 index 000000000000..bcc02aa43ebe --- /dev/null +++ b/tests/neg-macros/i14696.scala @@ -0,0 +1,27 @@ +import scala.quoted.* + +def test(a: Expr[Any])(using Quotes): Unit = a match + case '{ ${_}: String } | '{ ${_}: Int } => + case '{ $x1: String } | '{ ${_}: Int } => // error + case '{ $x: String } | '{ $x: Int } => // error // error + case '{ $x1: String } | '{ ${x2: Expr[Int]} } => // error // error + case '{ ${Str(x)}: String } | '{ ${y @ Str(z)}: Int } => // error // error + case '{ val x: Int = ???; ${_}(x): String } | '{ '{ val x: String = ???; ${_}(x): String }} => + case '{ val x: Int = ???; $f(x): String } | '{ val x: String = ???; ${_}(x): String } => // error + case '{ val x: Int = ???; $f(x): String } | '{ val x: String = ???; $f(x): String } => // error // error + case '{ val x: Int = ???; $f(x): String } | '{ val x: String = ???; $g(x): String } => // error // error + case '{ varargs(${_}*) } | '{ varargs(${_}*) } => + case '{ varargs($args*) } | '{ varargs(${_}*) } => // error + case '{ varargs($args*) } | '{ varargs($args*) } => // error // error + case '{ varargs($args1*) } | '{ varargs($args2*) } => // error // error + case '{ ${_}: t } | '{ ${_}: Int } => // error + case '{ ${_}: t } | '{ ${_}: t } => // error // error + case '{ ${_}: t } | '{ ${_}: u } => // error // error + case '{ type t; () } | '{ 1 } => // error + case '{ type t; () } | '{ type t; () } => // error // error + case '{ type t; () } | '{ type u; () } => // error // error + +def varargs(x: Any*): Unit = () + +object Str: + def unapply(x: Any): Option[String] = ???