Skip to content

Commit 0ba893e

Browse files
authored
Merge pull request #18453 from ChayimFriedman2/leading-or
Parse patterns with leading pipe properly in all places
2 parents 86a850d + 210ead8 commit 0ba893e

File tree

6 files changed

+73
-16
lines changed

6 files changed

+73
-16
lines changed

crates/parser/src/grammar.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub(crate) mod entry {
6767
}
6868

6969
pub(crate) fn pat_top(p: &mut Parser<'_>) {
70-
patterns::pattern_top(p);
70+
patterns::pattern(p);
7171
}
7272

7373
pub(crate) fn ty(p: &mut Parser<'_>) {
@@ -117,7 +117,7 @@ pub(crate) mod entry {
117117

118118
pub(crate) fn pattern(p: &mut Parser<'_>) {
119119
let m = p.start();
120-
patterns::pattern_top(p);
120+
patterns::pattern(p);
121121
if p.at(EOF) {
122122
m.abandon(p);
123123
return;

crates/parser/src/grammar/expressions/atom.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ fn for_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
660660
fn let_expr(p: &mut Parser<'_>) -> CompletedMarker {
661661
let m = p.start();
662662
p.bump(T![let]);
663-
patterns::pattern_top(p);
663+
patterns::pattern(p);
664664
p.expect(T![=]);
665665
expr_let(p);
666666
m.complete(p, LET_EXPR)

crates/parser/src/grammar/patterns.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,9 @@ const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
2020
const RANGE_PAT_END_FIRST: TokenSet =
2121
expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-], T![const]]));
2222

23-
pub(crate) fn pattern(p: &mut Parser<'_>) {
24-
let m = p.start();
25-
pattern_r(p, m, false, PAT_RECOVERY_SET);
26-
}
27-
2823
/// Parses a pattern list separated by pipes `|`.
29-
pub(super) fn pattern_top(p: &mut Parser<'_>) {
30-
pattern_top_r(p, PAT_RECOVERY_SET);
24+
pub(crate) fn pattern(p: &mut Parser<'_>) {
25+
pattern_r(p, PAT_RECOVERY_SET);
3126
}
3227

3328
pub(crate) fn pattern_single(p: &mut Parser<'_>) {
@@ -37,9 +32,7 @@ pub(crate) fn pattern_single(p: &mut Parser<'_>) {
3732
/// Parses a pattern list separated by pipes `|`
3833
/// using the given `recovery_set`.
3934
pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
40-
let m = p.start();
41-
let has_leading_pipe = p.eat(T![|]);
42-
pattern_r(p, m, has_leading_pipe, recovery_set);
35+
pattern_r(p, recovery_set);
4336
}
4437

4538
// test or_pattern
@@ -53,7 +46,10 @@ pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
5346
// }
5447
/// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
5548
/// given `recovery_set`.
56-
fn pattern_r(p: &mut Parser<'_>, m: Marker, has_leading_pipe: bool, recovery_set: TokenSet) {
49+
fn pattern_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
50+
let m = p.start();
51+
let has_leading_pipe = p.eat(T![|]);
52+
5753
pattern_single_r(p, recovery_set);
5854

5955
if !p.at(T![|]) && !has_leading_pipe {
@@ -319,6 +315,8 @@ fn record_pat_field(p: &mut Parser<'_>) {
319315
IDENT | INT_NUMBER if p.nth(1) == T![:] => {
320316
name_ref_or_index(p);
321317
p.bump(T![:]);
318+
// test record_field_pat_leading_or
319+
// fn foo() { let R { a: | 1 | 2 } = 0; }
322320
pattern(p);
323321
}
324322
// test_err record_pat_field_eq_recovery
@@ -438,7 +436,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
438436
}
439437
has_rest |= p.at(T![..]);
440438

441-
pattern_top(p);
439+
pattern(p);
442440
if !p.at(T![')']) {
443441
has_comma = true;
444442
p.expect(T![,]);
@@ -465,7 +463,7 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
465463

466464
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
467465
while !p.at(EOF) && !p.at(ket) {
468-
pattern_top(p);
466+
pattern(p);
469467
if !p.eat(T![,]) {
470468
if p.at_ts(PAT_TOP_FIRST) {
471469
p.error(format!("expected {:?}, got {:?}", T![,], p.current()));

crates/parser/test_data/generated/runner.rs

+4
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,10 @@ mod ok {
493493
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
494494
}
495495
#[test]
496+
fn record_field_pat_leading_or() {
497+
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_pat_leading_or.rs");
498+
}
499+
#[test]
496500
fn record_lit() { run_and_expect_no_errors("test_data/parser/inline/ok/record_lit.rs"); }
497501
#[test]
498502
fn record_literal_field_with_attr() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "foo"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
BLOCK_EXPR
12+
STMT_LIST
13+
L_CURLY "{"
14+
WHITESPACE " "
15+
LET_STMT
16+
LET_KW "let"
17+
WHITESPACE " "
18+
RECORD_PAT
19+
PATH
20+
PATH_SEGMENT
21+
NAME_REF
22+
IDENT "R"
23+
WHITESPACE " "
24+
RECORD_PAT_FIELD_LIST
25+
L_CURLY "{"
26+
WHITESPACE " "
27+
RECORD_PAT_FIELD
28+
NAME_REF
29+
IDENT "a"
30+
COLON ":"
31+
WHITESPACE " "
32+
OR_PAT
33+
PIPE "|"
34+
WHITESPACE " "
35+
LITERAL_PAT
36+
LITERAL
37+
INT_NUMBER "1"
38+
WHITESPACE " "
39+
PIPE "|"
40+
WHITESPACE " "
41+
LITERAL_PAT
42+
LITERAL
43+
INT_NUMBER "2"
44+
WHITESPACE " "
45+
R_CURLY "}"
46+
WHITESPACE " "
47+
EQ "="
48+
WHITESPACE " "
49+
LITERAL
50+
INT_NUMBER "0"
51+
SEMICOLON ";"
52+
WHITESPACE " "
53+
R_CURLY "}"
54+
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn foo() { let R { a: | 1 | 2 } = 0; }

0 commit comments

Comments
 (0)