From dfe0c546b1701660adab0b682d02745d98d6fdf9 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 23 Feb 2021 11:02:04 +0100 Subject: [PATCH] Vararg patterns must be variable patterns or wildcards Fixes #11457 --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 12 +++++++++--- docs/docs/internals/syntax.md | 2 +- docs/docs/reference/syntax.md | 2 +- tests/neg/i11457.scala | 6 ++++++ 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 tests/neg/i11457.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index ac8e0cd8cc64..421e59c28fe7 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2628,13 +2628,19 @@ object Parsers { ascription(p, location) else p - /** Pattern3 ::= InfixPattern [‘*’] + /** Pattern3 ::= InfixPattern + * | PatVar ‘*’ */ def pattern3(): Tree = val p = infixPattern() if followingIsVararg() then atSpan(in.skipToken()) { - Typed(p, Ident(tpnme.WILDCARD_STAR)) + p match + case p @ Ident(name) if name.isVarPattern => + Typed(p, Ident(tpnme.WILDCARD_STAR)) + case _ => + syntaxError(em"`*` must follow pattern variable") + p } else p @@ -2726,7 +2732,7 @@ object Parsers { if (in.token == RPAREN) Nil else patterns(location) /** ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ - * | ‘(’ [Patterns ‘,’] Pattern2 ‘*’ ‘)’ + * | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’ */ def argumentPatterns(): List[Tree] = inParens(patternsOpt(Location.InPatternArgs)) diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 6bdde243c630..7542988385f3 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -296,7 +296,7 @@ PatVar ::= varid | ‘_’ Patterns ::= Pattern {‘,’ Pattern} ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ Apply(fn, pats) - | ‘(’ [Patterns ‘,’] Pattern2 ‘*’ ‘)’ + | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’ ``` ### Type and Value Parameters diff --git a/docs/docs/reference/syntax.md b/docs/docs/reference/syntax.md index 354ea4c262a2..033ad9ad60d5 100644 --- a/docs/docs/reference/syntax.md +++ b/docs/docs/reference/syntax.md @@ -290,7 +290,7 @@ PatVar ::= varid | ‘_’ Patterns ::= Pattern {‘,’ Pattern} ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ - | ‘(’ [Patterns ‘,’] Pattern2 ‘*’ ‘)’ + | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’ ``` ### Type and Value Parameters diff --git a/tests/neg/i11457.scala b/tests/neg/i11457.scala new file mode 100644 index 000000000000..c0ba5720401f --- /dev/null +++ b/tests/neg/i11457.scala @@ -0,0 +1,6 @@ + +val x = Seq(1, 2) match + case Seq(x, y*) => println(y) // prints List(2) which looks correct + +val y = Seq(1, 2) match + case Seq(x, (y)*) => println(y) // error