diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 7e21a808da0..bc1224af9b2 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -13,6 +13,8 @@ pub(super) const PATTERN_FIRST: TokenSet = T![.], ])); +const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]])); + pub(crate) fn pattern(p: &mut Parser<'_>) { pattern_r(p, PAT_RECOVERY_SET); } @@ -228,6 +230,7 @@ fn path_or_macro_pat(p: &mut Parser<'_>) -> CompletedMarker { // let S(_) = (); // let S(_,) = (); // let S(_, .. , x) = (); +// let S(| a) = (); // } fn tuple_pat_fields(p: &mut Parser<'_>) { assert!(p.at(T!['('])); @@ -363,6 +366,7 @@ fn ref_pat(p: &mut Parser<'_>) -> CompletedMarker { // let (a,) = (); // let (..) = (); // let () = (); +// let (| a | a, | b) = ((),()); // } fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker { assert!(p.at(T!['('])); @@ -373,13 +377,13 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker { let mut has_rest = false; while !p.at(EOF) && !p.at(T![')']) { has_pat = true; - if !p.at_ts(PATTERN_FIRST) { + if !p.at_ts(PAT_TOP_FIRST) { p.error("expected a pattern"); break; } has_rest |= p.at(T![..]); - pattern(p); + pattern_top(p); if !p.at(T![')']) { has_comma = true; p.expect(T![,]); @@ -393,6 +397,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker { // test slice_pat // fn main() { // let [a, b, ..] = []; +// let [| a, ..] = []; // } fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker { assert!(p.at(T!['['])); @@ -405,12 +410,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker { fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) { while !p.at(EOF) && !p.at(ket) { - if !p.at_ts(PATTERN_FIRST) { + if !p.at_ts(PAT_TOP_FIRST) { p.error("expected a pattern"); break; } - pattern(p); + pattern_top(p); if !p.at(ket) { p.expect(T![,]); } diff --git a/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast b/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast index 235a9d7f404..dff72ba886f 100644 --- a/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast +++ b/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast @@ -37,6 +37,29 @@ SOURCE_FILE L_BRACK "[" R_BRACK "]" SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + SLICE_PAT + L_BRACK "[" + PIPE "|" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + REST_PAT + DOT2 ".." + R_BRACK "]" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ARRAY_EXPR + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs b/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs index 7955973b952..855ba89b1e9 100644 --- a/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs +++ b/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs @@ -1,3 +1,4 @@ fn main() { let [a, b, ..] = []; + let [| a, ..] = []; } diff --git a/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast b/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast index 3cdaf32b572..55baf2fdcb4 100644 --- a/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast +++ b/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast @@ -100,6 +100,29 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + TUPLE_STRUCT_PAT + PATH + PATH_SEGMENT + NAME_REF + IDENT "S" + L_PAREN "(" + PIPE "|" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "a" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs b/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs index 0dfe6362967..8ec6f4ca93e 100644 --- a/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs +++ b/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs @@ -3,4 +3,5 @@ fn foo() { let S(_) = (); let S(_,) = (); let S(_, .. , x) = (); + let S(| a) = (); } diff --git a/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast b/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast index cebe98c43aa..1a01e0f6938 100644 --- a/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast +++ b/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast @@ -85,6 +85,46 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + TUPLE_PAT + L_PAREN "(" + PIPE "|" + WHITESPACE " " + OR_PAT + IDENT_PAT + NAME + IDENT "a" + WHITESPACE " " + PIPE "|" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + PIPE "|" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "b" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + COMMA "," + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs b/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs index ba719879d4c..fbd7f48f66b 100644 --- a/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs +++ b/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs @@ -3,4 +3,5 @@ fn main() { let (a,) = (); let (..) = (); let () = (); + let (| a | a, | b) = ((),()); }