aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/patterns.rs')
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs49
1 files changed, 27 insertions, 22 deletions
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 32cde7de6..dd1d25b07 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -34,17 +34,20 @@ pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
34 // 200 .. 301=> (), 34 // 200 .. 301=> (),
35 // } 35 // }
36 // } 36 // }
37 if p.at(T![...]) || p.at(T![..=]) || p.at(T![..]) { 37 for &range_op in [T![...], T![..=], T![..]].iter() {
38 let m = lhs.precede(p); 38 if p.at(range_op) {
39 p.bump(); 39 let m = lhs.precede(p);
40 atom_pat(p, recovery_set); 40 p.bump(range_op);
41 m.complete(p, RANGE_PAT); 41 atom_pat(p, recovery_set);
42 m.complete(p, RANGE_PAT);
43 return;
44 }
42 } 45 }
43 // test marco_pat 46 // test marco_pat
44 // fn main() { 47 // fn main() {
45 // let m!(x) = 0; 48 // let m!(x) = 0;
46 // } 49 // }
47 else if lhs.kind() == PATH_PAT && p.at(T![!]) { 50 if lhs.kind() == PATH_PAT && p.at(T![!]) {
48 let m = lhs.precede(p); 51 let m = lhs.precede(p);
49 items::macro_call_after_excl(p); 52 items::macro_call_after_excl(p);
50 m.complete(p, MACRO_CALL); 53 m.complete(p, MACRO_CALL);
@@ -56,14 +59,16 @@ const PAT_RECOVERY_SET: TokenSet =
56 token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; 59 token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA];
57 60
58fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { 61fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
59 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
60 // (T![x]).
61 let is_path_or_macro_pat =
62 |la1| la1 == T![::] || la1 == T!['('] || la1 == T!['{'] || la1 == T![!];
63
64 let m = match p.nth(0) { 62 let m = match p.nth(0) {
65 T![box] => box_pat(p), 63 T![box] => box_pat(p),
66 T![ref] | T![mut] | IDENT if !is_path_or_macro_pat(p.nth(1)) => bind_pat(p, true), 64 T![ref] | T![mut] => bind_pat(p, true),
65 IDENT => match p.nth(1) {
66 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
67 // (T![x]).
68 T!['('] | T!['{'] | T![!] => path_pat(p),
69 T![:] if p.nth_at(1, T![::]) => path_pat(p),
70 _ => bind_pat(p, true),
71 },
67 72
68 _ if paths::is_use_path_start(p) => path_pat(p), 73 _ if paths::is_use_path_start(p) => path_pat(p),
69 _ if is_literal_pat_start(p) => literal_pat(p), 74 _ if is_literal_pat_start(p) => literal_pat(p),
@@ -100,7 +105,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker {
100 assert!(is_literal_pat_start(p)); 105 assert!(is_literal_pat_start(p));
101 let m = p.start(); 106 let m = p.start();
102 if p.at(T![-]) { 107 if p.at(T![-]) {
103 p.bump(); 108 p.bump_any();
104 } 109 }
105 expressions::literal(p); 110 expressions::literal(p);
106 m.complete(p, LITERAL_PAT) 111 m.complete(p, LITERAL_PAT)
@@ -140,7 +145,7 @@ fn path_pat(p: &mut Parser) -> CompletedMarker {
140// } 145// }
141fn tuple_pat_fields(p: &mut Parser) { 146fn tuple_pat_fields(p: &mut Parser) {
142 assert!(p.at(T!['('])); 147 assert!(p.at(T!['(']));
143 p.bump(); 148 p.bump_any();
144 pat_list(p, T![')']); 149 pat_list(p, T![')']);
145 p.expect(T![')']); 150 p.expect(T![')']);
146} 151}
@@ -155,10 +160,10 @@ fn tuple_pat_fields(p: &mut Parser) {
155fn record_field_pat_list(p: &mut Parser) { 160fn record_field_pat_list(p: &mut Parser) {
156 assert!(p.at(T!['{'])); 161 assert!(p.at(T!['{']));
157 let m = p.start(); 162 let m = p.start();
158 p.bump(); 163 p.bump_any();
159 while !p.at(EOF) && !p.at(T!['}']) { 164 while !p.at(EOF) && !p.at(T!['}']) {
160 match p.current() { 165 match p.current() {
161 T![..] => p.bump(), 166 T![.] if p.at(T![..]) => p.bump(T![..]),
162 IDENT if p.nth(1) == T![:] => record_field_pat(p), 167 IDENT if p.nth(1) == T![:] => record_field_pat(p),
163 T!['{'] => error_block(p, "expected ident"), 168 T!['{'] => error_block(p, "expected ident"),
164 T![box] => { 169 T![box] => {
@@ -182,7 +187,7 @@ fn record_field_pat(p: &mut Parser) {
182 187
183 let m = p.start(); 188 let m = p.start();
184 name(p); 189 name(p);
185 p.bump(); 190 p.bump_any();
186 pattern(p); 191 pattern(p);
187 m.complete(p, RECORD_FIELD_PAT); 192 m.complete(p, RECORD_FIELD_PAT);
188} 193}
@@ -192,7 +197,7 @@ fn record_field_pat(p: &mut Parser) {
192fn placeholder_pat(p: &mut Parser) -> CompletedMarker { 197fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
193 assert!(p.at(T![_])); 198 assert!(p.at(T![_]));
194 let m = p.start(); 199 let m = p.start();
195 p.bump(); 200 p.bump_any();
196 m.complete(p, PLACEHOLDER_PAT) 201 m.complete(p, PLACEHOLDER_PAT)
197} 202}
198 203
@@ -204,7 +209,7 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
204fn ref_pat(p: &mut Parser) -> CompletedMarker { 209fn ref_pat(p: &mut Parser) -> CompletedMarker {
205 assert!(p.at(T![&])); 210 assert!(p.at(T![&]));
206 let m = p.start(); 211 let m = p.start();
207 p.bump(); 212 p.bump_any();
208 p.eat(T![mut]); 213 p.eat(T![mut]);
209 pattern(p); 214 pattern(p);
210 m.complete(p, REF_PAT) 215 m.complete(p, REF_PAT)
@@ -228,7 +233,7 @@ fn tuple_pat(p: &mut Parser) -> CompletedMarker {
228fn slice_pat(p: &mut Parser) -> CompletedMarker { 233fn slice_pat(p: &mut Parser) -> CompletedMarker {
229 assert!(p.at(T!['['])); 234 assert!(p.at(T!['[']));
230 let m = p.start(); 235 let m = p.start();
231 p.bump(); 236 p.bump_any();
232 pat_list(p, T![']']); 237 pat_list(p, T![']']);
233 p.expect(T![']']); 238 p.expect(T![']']);
234 m.complete(p, SLICE_PAT) 239 m.complete(p, SLICE_PAT)
@@ -237,7 +242,7 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker {
237fn pat_list(p: &mut Parser, ket: SyntaxKind) { 242fn pat_list(p: &mut Parser, ket: SyntaxKind) {
238 while !p.at(EOF) && !p.at(ket) { 243 while !p.at(EOF) && !p.at(ket) {
239 match p.current() { 244 match p.current() {
240 T![..] => p.bump(), 245 T![.] if p.at(T![..]) => p.bump(T![..]),
241 _ => { 246 _ => {
242 if !p.at_ts(PATTERN_FIRST) { 247 if !p.at_ts(PATTERN_FIRST) {
243 p.error("expected a pattern"); 248 p.error("expected a pattern");
@@ -281,7 +286,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
281fn box_pat(p: &mut Parser) -> CompletedMarker { 286fn box_pat(p: &mut Parser) -> CompletedMarker {
282 assert!(p.at(T![box])); 287 assert!(p.at(T![box]));
283 let m = p.start(); 288 let m = p.start();
284 p.bump(); 289 p.bump_any();
285 pattern(p); 290 pattern(p);
286 m.complete(p, BOX_PAT) 291 m.complete(p, BOX_PAT)
287} 292}