about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs24
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rast54
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rs1
6 files changed, 73 insertions, 16 deletions
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
index a5c031ad609..a50a2182a7b 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
@@ -67,7 +67,7 @@ pub(crate) mod entry {
         }
 
         pub(crate) fn pat_top(p: &mut Parser<'_>) {
-            patterns::pattern_top(p);
+            patterns::pattern(p);
         }
 
         pub(crate) fn ty(p: &mut Parser<'_>) {
@@ -117,7 +117,7 @@ pub(crate) mod entry {
 
         pub(crate) fn pattern(p: &mut Parser<'_>) {
             let m = p.start();
-            patterns::pattern_top(p);
+            patterns::pattern(p);
             if p.at(EOF) {
                 m.abandon(p);
                 return;
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
index 2333e6c862b..97e0392ce15 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -660,7 +660,7 @@ fn for_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
 fn let_expr(p: &mut Parser<'_>) -> CompletedMarker {
     let m = p.start();
     p.bump(T![let]);
-    patterns::pattern_top(p);
+    patterns::pattern(p);
     p.expect(T![=]);
     expr_let(p);
     m.complete(p, LET_EXPR)
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
index ed01fca2acd..460051a0f4a 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
@@ -20,14 +20,9 @@ const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
 const RANGE_PAT_END_FIRST: TokenSet =
     expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-], T![const]]));
 
-pub(crate) fn pattern(p: &mut Parser<'_>) {
-    let m = p.start();
-    pattern_r(p, m, false, PAT_RECOVERY_SET);
-}
-
 /// Parses a pattern list separated by pipes `|`.
-pub(super) fn pattern_top(p: &mut Parser<'_>) {
-    pattern_top_r(p, PAT_RECOVERY_SET);
+pub(crate) fn pattern(p: &mut Parser<'_>) {
+    pattern_r(p, PAT_RECOVERY_SET);
 }
 
 pub(crate) fn pattern_single(p: &mut Parser<'_>) {
@@ -37,9 +32,7 @@ pub(crate) fn pattern_single(p: &mut Parser<'_>) {
 /// Parses a pattern list separated by pipes `|`
 /// using the given `recovery_set`.
 pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
-    let m = p.start();
-    let has_leading_pipe = p.eat(T![|]);
-    pattern_r(p, m, has_leading_pipe, recovery_set);
+    pattern_r(p, recovery_set);
 }
 
 // test or_pattern
@@ -53,7 +46,10 @@ pub(super) fn pattern_top_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
 // }
 /// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
 /// given `recovery_set`.
-fn pattern_r(p: &mut Parser<'_>, m: Marker, has_leading_pipe: bool, recovery_set: TokenSet) {
+fn pattern_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
+    let m = p.start();
+    let has_leading_pipe = p.eat(T![|]);
+
     pattern_single_r(p, recovery_set);
 
     if !p.at(T![|]) && !has_leading_pipe {
@@ -319,6 +315,8 @@ fn record_pat_field(p: &mut Parser<'_>) {
         IDENT | INT_NUMBER if p.nth(1) == T![:] => {
             name_ref_or_index(p);
             p.bump(T![:]);
+            // test record_field_pat_leading_or
+            // fn foo() { let R { a: | 1 | 2 } = 0; }
             pattern(p);
         }
         // test_err record_pat_field_eq_recovery
@@ -438,7 +436,7 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker {
         }
         has_rest |= p.at(T![..]);
 
-        pattern_top(p);
+        pattern(p);
         if !p.at(T![')']) {
             has_comma = true;
             p.expect(T![,]);
@@ -465,7 +463,7 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
 
 fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
     while !p.at(EOF) && !p.at(ket) {
-        pattern_top(p);
+        pattern(p);
         if !p.eat(T![,]) {
             if p.at_ts(PAT_TOP_FIRST) {
                 p.error(format!("expected {:?}, got {:?}", T![,], p.current()));
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
index 5b41dd07adc..62b381b6688 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -493,6 +493,10 @@ mod ok {
         run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
     }
     #[test]
+    fn record_field_pat_leading_or() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_field_pat_leading_or.rs");
+    }
+    #[test]
     fn record_lit() { run_and_expect_no_errors("test_data/parser/inline/ok/record_lit.rs"); }
     #[test]
     fn record_literal_field_with_attr() {
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rast
new file mode 100644
index 00000000000..4ef6c1c45f5
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rast
@@ -0,0 +1,54 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          RECORD_PAT
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "R"
+            WHITESPACE " "
+            RECORD_PAT_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_PAT_FIELD
+                NAME_REF
+                  IDENT "a"
+                COLON ":"
+                WHITESPACE " "
+                OR_PAT
+                  PIPE "|"
+                  WHITESPACE " "
+                  LITERAL_PAT
+                    LITERAL
+                      INT_NUMBER "1"
+                  WHITESPACE " "
+                  PIPE "|"
+                  WHITESPACE " "
+                  LITERAL_PAT
+                    LITERAL
+                      INT_NUMBER "2"
+              WHITESPACE " "
+              R_CURLY "}"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "0"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rs
new file mode 100644
index 00000000000..a5e7510c140
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_pat_leading_or.rs
@@ -0,0 +1 @@
+fn foo() { let R { a: | 1 | 2 } = 0; }