]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / parser / src / grammar / patterns.rs
index 4cbf1030614977af5e9cb5b39a93d92c528af94d..bc1224af9b212c639bcf80026661554887f19d07 100644 (file)
@@ -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);
 }
@@ -75,6 +77,16 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
         //         Some(1..) => ()
         //     }
         //
+        //     match () {
+        //         S { a: 0 } => (),
+        //         S { a: 1.. } => (),
+        //     }
+        //
+        //     match () {
+        //         [0] => (),
+        //         [1..] => (),
+        //     }
+        //
         //     match (10 as u8, 5 as u8) {
         //         (0, _) => (),
         //         (1.., _) => ()
@@ -88,11 +100,27 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
                 let m = lhs.precede(p);
                 p.bump(range_op);
 
-                // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
-                //       ^                ^                ^
-                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) {
+                // testing if we're at one of the following positions:
+                // `0 .. =>`
+                //       ^
+                // `let 0 .. =`
+                //           ^
+                // `let 0..: _ =`
+                //         ^
+                // (1.., _)
+                //     ^
+                // `Some(0 .. )`
+                //            ^
+                // `S { t: 0.. }`
+                //             ^
+                // `[0..]`
+                //      ^
+                if matches!(p.current(), T![=] | T![,] | T![:] | T![')'] | T!['}'] | T![']']) {
                     // test half_open_range_pat
-                    // fn f() { let 0 .. = 1u32; }
+                    // fn f() {
+                    //     let 0 .. = 1u32;
+                    //     let 0..: _ = 1u32;
+                    // }
                 } else {
                     atom_pat(p, recovery_set);
                 }
@@ -202,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!['(']));
@@ -337,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!['(']));
@@ -347,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![,]);
@@ -367,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!['[']));
@@ -379,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![,]);
         }