Skip to content

Commit e73b7a9

Browse files
committed
Auto merge of #13096 - jonas-schievink:parse-more-or-pats, r=jonas-schievink
fix: Allow leading `|` in more pattern positions fixes #12894, fixes #13094 Oddly, the leading `|` token does not end up inside the `OR_PAT` node, since `pattern_top_r` consumes it first. This is a preexisting issue in match arms though, so I didn't fix it here.
2 parents f045f14 + 8969655 commit e73b7a9

File tree

7 files changed

+98
-4
lines changed

7 files changed

+98
-4
lines changed

crates/parser/src/grammar/patterns.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub(super) const PATTERN_FIRST: TokenSet =
1313
T![.],
1414
]));
1515

16+
const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
17+
1618
pub(crate) fn pattern(p: &mut Parser<'_>) {
1719
pattern_r(p, PAT_RECOVERY_SET);
1820
}
@@ -228,6 +230,7 @@ fn path_or_macro_pat(p: &mut Parser<'_>) -> CompletedMarker {
228230
// let S(_) = ();
229231
// let S(_,) = ();
230232
// let S(_, .. , x) = ();
233+
// let S(| a) = ();
231234
// }
232235
fn tuple_pat_fields(p: &mut Parser<'_>) {
233236
assert!(p.at(T!['(']));
@@ -363,6 +366,7 @@ fn ref_pat(p: &mut Parser<'_>) -> CompletedMarker {
363366
// let (a,) = ();
364367
// let (..) = ();
365368
// let () = ();
369+
// let (| a | a, | b) = ((),());
366370
// }
367371
fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
368372
assert!(p.at(T!['(']));
@@ -373,13 +377,13 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
373377
let mut has_rest = false;
374378
while !p.at(EOF) && !p.at(T![')']) {
375379
has_pat = true;
376-
if !p.at_ts(PATTERN_FIRST) {
380+
if !p.at_ts(PAT_TOP_FIRST) {
377381
p.error("expected a pattern");
378382
break;
379383
}
380384
has_rest |= p.at(T![..]);
381385

382-
pattern(p);
386+
pattern_top(p);
383387
if !p.at(T![')']) {
384388
has_comma = true;
385389
p.expect(T![,]);
@@ -393,6 +397,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
393397
// test slice_pat
394398
// fn main() {
395399
// let [a, b, ..] = [];
400+
// let [| a, ..] = [];
396401
// }
397402
fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
398403
assert!(p.at(T!['[']));
@@ -405,12 +410,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
405410

406411
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
407412
while !p.at(EOF) && !p.at(ket) {
408-
if !p.at_ts(PATTERN_FIRST) {
413+
if !p.at_ts(PAT_TOP_FIRST) {
409414
p.error("expected a pattern");
410415
break;
411416
}
412417

413-
pattern(p);
418+
pattern_top(p);
414419
if !p.at(ket) {
415420
p.expect(T![,]);
416421
}

crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast

+23
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,29 @@ SOURCE_FILE
3737
L_BRACK "["
3838
R_BRACK "]"
3939
SEMICOLON ";"
40+
WHITESPACE "\n "
41+
LET_STMT
42+
LET_KW "let"
43+
WHITESPACE " "
44+
SLICE_PAT
45+
L_BRACK "["
46+
PIPE "|"
47+
WHITESPACE " "
48+
IDENT_PAT
49+
NAME
50+
IDENT "a"
51+
COMMA ","
52+
WHITESPACE " "
53+
REST_PAT
54+
DOT2 ".."
55+
R_BRACK "]"
56+
WHITESPACE " "
57+
EQ "="
58+
WHITESPACE " "
59+
ARRAY_EXPR
60+
L_BRACK "["
61+
R_BRACK "]"
62+
SEMICOLON ";"
4063
WHITESPACE "\n"
4164
R_CURLY "}"
4265
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
fn main() {
22
let [a, b, ..] = [];
3+
let [| a, ..] = [];
34
}

crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast

+23
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,29 @@ SOURCE_FILE
100100
L_PAREN "("
101101
R_PAREN ")"
102102
SEMICOLON ";"
103+
WHITESPACE "\n "
104+
LET_STMT
105+
LET_KW "let"
106+
WHITESPACE " "
107+
TUPLE_STRUCT_PAT
108+
PATH
109+
PATH_SEGMENT
110+
NAME_REF
111+
IDENT "S"
112+
L_PAREN "("
113+
PIPE "|"
114+
WHITESPACE " "
115+
IDENT_PAT
116+
NAME
117+
IDENT "a"
118+
R_PAREN ")"
119+
WHITESPACE " "
120+
EQ "="
121+
WHITESPACE " "
122+
TUPLE_EXPR
123+
L_PAREN "("
124+
R_PAREN ")"
125+
SEMICOLON ";"
103126
WHITESPACE "\n"
104127
R_CURLY "}"
105128
WHITESPACE "\n"

crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ fn foo() {
33
let S(_) = ();
44
let S(_,) = ();
55
let S(_, .. , x) = ();
6+
let S(| a) = ();
67
}

crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast

+40
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,46 @@ SOURCE_FILE
8585
L_PAREN "("
8686
R_PAREN ")"
8787
SEMICOLON ";"
88+
WHITESPACE "\n "
89+
LET_STMT
90+
LET_KW "let"
91+
WHITESPACE " "
92+
TUPLE_PAT
93+
L_PAREN "("
94+
PIPE "|"
95+
WHITESPACE " "
96+
OR_PAT
97+
IDENT_PAT
98+
NAME
99+
IDENT "a"
100+
WHITESPACE " "
101+
PIPE "|"
102+
WHITESPACE " "
103+
IDENT_PAT
104+
NAME
105+
IDENT "a"
106+
COMMA ","
107+
WHITESPACE " "
108+
PIPE "|"
109+
WHITESPACE " "
110+
IDENT_PAT
111+
NAME
112+
IDENT "b"
113+
R_PAREN ")"
114+
WHITESPACE " "
115+
EQ "="
116+
WHITESPACE " "
117+
TUPLE_EXPR
118+
L_PAREN "("
119+
TUPLE_EXPR
120+
L_PAREN "("
121+
R_PAREN ")"
122+
COMMA ","
123+
TUPLE_EXPR
124+
L_PAREN "("
125+
R_PAREN ")"
126+
R_PAREN ")"
127+
SEMICOLON ";"
88128
WHITESPACE "\n"
89129
R_CURLY "}"
90130
WHITESPACE "\n"

crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ fn main() {
33
let (a,) = ();
44
let (..) = ();
55
let () = ();
6+
let (| a | a, | b) = ((),());
67
}

0 commit comments

Comments
 (0)