summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs')
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs47
1 files changed, 39 insertions, 8 deletions
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 4cbf10306..bc1224af9 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
+++ b/src/tools/rust-analyzer/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);
}
@@ -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![,]);
}