diff options
Diffstat (limited to 'crates/ra_parser/src/grammar/patterns.rs')
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 49 |
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 | ||
58 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | 61 | fn 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 | // } |
141 | fn tuple_pat_fields(p: &mut Parser) { | 146 | fn 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) { | |||
155 | fn record_field_pat_list(p: &mut Parser) { | 160 | fn 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) { | |||
192 | fn placeholder_pat(p: &mut Parser) -> CompletedMarker { | 197 | fn 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 { | |||
204 | fn ref_pat(p: &mut Parser) -> CompletedMarker { | 209 | fn 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 { | |||
228 | fn slice_pat(p: &mut Parser) -> CompletedMarker { | 233 | fn 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 { | |||
237 | fn pat_list(p: &mut Parser, ket: SyntaxKind) { | 242 | fn 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 { | |||
281 | fn box_pat(p: &mut Parser) -> CompletedMarker { | 286 | fn 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 | } |