Skip to content

Commit 7995bfd

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 ceca748 commit 7995bfd

File tree

4 files changed

+17
-15
lines changed

4 files changed

+17
-15
lines changed

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

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

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

@@ -2855,13 +2855,13 @@ object Parsers {
28552855
if (isIdent(nme.raw.BAR)) { in.nextToken(); pattern1(location) :: patternAlts(location) }
28562856
else Nil
28572857

2858-
/** Pattern1 ::= PatVar Ascription
2859-
* | [‘-’] integerLiteral Ascription
2860-
* | [‘-’] floatingPointLiteral Ascription
2858+
/** Pattern1 ::= PatVar `:` RefinedType
2859+
* | [‘-’] integerLiteral `:` RefinedType
2860+
* | [‘-’] floatingPointLiteral `:` RefinedType
28612861
* | Pattern2
28622862
*/
28632863
def pattern1(location: Location = Location.InPattern): Tree =
2864-
val p = pattern2()
2864+
val p = pattern2(location)
28652865
if in.isColon then
28662866
val isVariableOrNumber = isVarPattern(p) || p.isInstanceOf[Number]
28672867
if !isVariableOrNumber then
@@ -2879,11 +2879,10 @@ object Parsers {
28792879
else p
28802880

28812881
/** Pattern3 ::= InfixPattern
2882-
* | PatVar ‘*’
28832882
*/
2884-
def pattern3(): Tree =
2883+
def pattern3(location: Location): Tree =
28852884
val p = infixPattern()
2886-
if followingIsVararg() then
2885+
if location.inArgs && followingIsVararg() then
28872886
val start = in.skipToken()
28882887
p match
28892888
case p @ Ident(name) if name.isVarPattern =>
@@ -2895,10 +2894,10 @@ object Parsers {
28952894

28962895
/** Pattern2 ::= [id `@'] Pattern3
28972896
*/
2898-
val pattern2: () => Tree = () => pattern3() match
2897+
val pattern2: Location => Tree = location => pattern3(location) match
28992898
case p @ Ident(name) if in.token == AT =>
29002899
val offset = in.skipToken()
2901-
pattern3() match {
2900+
pattern3(location) match {
29022901
case pt @ Bind(nme.WILDCARD, pt1: Typed) if pt.mods.is(Given) =>
29032902
atSpan(startOffset(p), 0) { Bind(name, pt1).withMods(pt.mods) }
29042903
case Typed(Ident(nme.WILDCARD), pt @ Ident(tpnme.WILDCARD_STAR)) =>
@@ -2928,6 +2927,7 @@ object Parsers {
29282927
* | XmlPattern
29292928
* | `(' [Patterns] `)'
29302929
* | SimplePattern1 [TypeArgs] [ArgumentPatterns]
2930+
* | ‘given’ RefinedType
29312931
* SimplePattern1 ::= SimpleRef
29322932
* | SimplePattern1 `.' id
29332933
* PatVar ::= id
@@ -3569,7 +3569,7 @@ object Parsers {
35693569
* VarDcl ::= id {`,' id} `:' Type
35703570
*/
35713571
def patDefOrDcl(start: Offset, mods: Modifiers): Tree = atSpan(start, nameStart) {
3572-
val first = pattern2()
3572+
val first = pattern2(Location.InPattern)
35733573
var lhs = first match {
35743574
case id: Ident if in.token == COMMA =>
35753575
in.nextToken()

docs/_docs/internals/syntax.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ Pattern1 ::= PatVar ‘:’ RefinedType
318318
| [‘-’] integerLiteral ‘:’ RefinedType Typed(pat, tpe)
319319
| [‘-’] floatingPointLiteral ‘:’ RefinedType Typed(pat, tpe)
320320
| Pattern2
321-
Pattern2 ::= [id ‘@’] InfixPattern [‘*’] Bind(name, pat)
321+
Pattern2 ::= [id ‘@’] InfixPattern Bind(name, pat)
322322
InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
323323
SimplePattern ::= PatVar Ident(wildcard)
324324
| Literal Bind(name, Ident(wildcard))
@@ -357,8 +357,8 @@ ClsParam ::= {Annotation}
357357
[{Modifier} (‘val’ | ‘var’) | ‘inline’] Param
358358
359359
DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
360-
DefParamClause ::= DefTypeParamClause
361-
| DefTermParamClause
360+
DefParamClause ::= DefTypeParamClause
361+
| DefTermParamClause
362362
| UsingParamClause
363363
TypelessClauses ::= TypelessClause {TypelessClause}
364364
TypelessClause ::= DefTermParamClause

docs/_docs/reference/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ Pattern1 ::= PatVar ‘:’ RefinedType
316316
| [‘-’] integerLiteral ‘:’ RefinedType
317317
| [‘-’] floatingPointLiteral ‘:’ RefinedType
318318
| Pattern2
319-
Pattern2 ::= [id ‘@’] InfixPattern [‘*’]
319+
Pattern2 ::= [id ‘@’] InfixPattern
320320
InfixPattern ::= SimplePattern { id [nl] SimplePattern }
321321
SimplePattern ::= PatVar
322322
| 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)