Skip to content

Commit bf6974e

Browse files
committed
Fix syntax and parsing of vararg patterns
Syntax: Remove outdated `*` after InfixPattern Parsing: Only allow vararg `*` in ArgumentPatterns Fixes #17443
1 parent 46b30cc commit bf6974e

File tree

4 files changed

+15
-13
lines changed

4 files changed

+15
-13
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,7 @@ object Parsers {
16661666
if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil
16671667

16681668
/** InfixType ::= RefinedType {id [nl] RefinedType}
1669-
* | RefinedType `^`
1669+
* | RefinedType `^` // under capture checking
16701670
*/
16711671
def infixType(): Tree = infixTypeRest(refinedType())
16721672

@@ -2881,13 +2881,13 @@ object Parsers {
28812881
if (isIdent(nme.raw.BAR)) { in.nextToken(); pattern1(location) :: patternAlts(location) }
28822882
else Nil
28832883

2884-
/** Pattern1 ::= PatVar Ascription
2885-
* | [‘-’] integerLiteral Ascription
2886-
* | [‘-’] floatingPointLiteral Ascription
2884+
/** Pattern1 ::= PatVar `:` RefinedType
2885+
* | [‘-’] integerLiteral `:` RefinedType
2886+
* | [‘-’] floatingPointLiteral `:` RefinedType
28872887
* | Pattern2
28882888
*/
28892889
def pattern1(location: Location = Location.InPattern): Tree =
2890-
val p = pattern2()
2890+
val p = pattern2(location)
28912891
if in.isColon then
28922892
val isVariableOrNumber = isVarPattern(p) || p.isInstanceOf[Number]
28932893
if !isVariableOrNumber then
@@ -2905,11 +2905,10 @@ object Parsers {
29052905
else p
29062906

29072907
/** Pattern3 ::= InfixPattern
2908-
* | PatVar ‘*’
29092908
*/
2910-
def pattern3(): Tree =
2909+
def pattern3(location: Location): Tree =
29112910
val p = infixPattern()
2912-
if followingIsVararg() then
2911+
if location.inArgs && followingIsVararg() then
29132912
val start = in.skipToken()
29142913
p match
29152914
case p @ Ident(name) if name.isVarPattern =>
@@ -2921,10 +2920,10 @@ object Parsers {
29212920

29222921
/** Pattern2 ::= [id `@'] Pattern3
29232922
*/
2924-
val pattern2: () => Tree = () => pattern3() match
2923+
val pattern2: Location => Tree = location => pattern3(location) match
29252924
case p @ Ident(name) if in.token == AT =>
29262925
val offset = in.skipToken()
2927-
pattern3() match {
2926+
pattern3(location) match {
29282927
case pt @ Bind(nme.WILDCARD, pt1: Typed) if pt.mods.is(Given) =>
29292928
atSpan(startOffset(p), 0) { Bind(name, pt1).withMods(pt.mods) }
29302929
case Typed(Ident(nme.WILDCARD), pt @ Ident(tpnme.WILDCARD_STAR)) =>
@@ -2954,6 +2953,7 @@ object Parsers {
29542953
* | XmlPattern
29552954
* | `(' [Patterns] `)'
29562955
* | SimplePattern1 [TypeArgs] [ArgumentPatterns]
2956+
* | ‘given’ RefinedType
29572957
* SimplePattern1 ::= SimpleRef
29582958
* | SimplePattern1 `.' id
29592959
* PatVar ::= id
@@ -3597,7 +3597,7 @@ object Parsers {
35973597
* VarDcl ::= id {`,' id} `:' Type
35983598
*/
35993599
def patDefOrDcl(start: Offset, mods: Modifiers): Tree = atSpan(start, nameStart) {
3600-
val first = pattern2()
3600+
val first = pattern2(Location.InPattern)
36013601
var lhs = first match {
36023602
case id: Ident if in.token == COMMA =>
36033603
in.nextToken()

docs/_docs/internals/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Pattern1 ::= PatVar ‘:’ RefinedType
317317
| [‘-’] integerLiteral ‘:’ RefinedType Typed(pat, tpe)
318318
| [‘-’] floatingPointLiteral ‘:’ RefinedType Typed(pat, tpe)
319319
| Pattern2
320-
Pattern2 ::= [id ‘@’] InfixPattern [‘*’] Bind(name, pat)
320+
Pattern2 ::= [id ‘@’] InfixPattern Bind(name, pat)
321321
InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
322322
SimplePattern ::= PatVar Ident(wildcard)
323323
| Literal Bind(name, Ident(wildcard))

docs/_docs/reference/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ Pattern1 ::= PatVar ‘:’ RefinedType
318318
| [‘-’] integerLiteral ‘:’ RefinedType
319319
| [‘-’] floatingPointLiteral ‘:’ RefinedType
320320
| Pattern2
321-
Pattern2 ::= [id ‘@’] InfixPattern [‘*’]
321+
Pattern2 ::= [id ‘@’] InfixPattern
322322
InfixPattern ::= SimplePattern { id [nl] SimplePattern }
323323
SimplePattern ::= PatVar
324324
| Literal

tests/neg/i17443.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def run() =
2+
val x = List(1) match { case (xs*) => xs } // error

0 commit comments

Comments
 (0)