diff options
author | Dylan MacKenzie <[email protected]> | 2019-09-15 01:06:08 +0100 |
---|---|---|
committer | Dylan MacKenzie <[email protected]> | 2019-09-15 01:08:22 +0100 |
commit | 4a3a15f0e7449d84dad18d0c7d2c2898471dbd16 (patch) | |
tree | bd4eeb80f58fddfaf7f465734ad178bbbdc6a338 /crates/ra_parser/src/grammar | |
parent | 426112c97e587dfdaa79bcec0d4a37bef3c6b474 (diff) |
Parse `..` as a proper pattern
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index dd1d25b07..919b0f37d 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -2,7 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST | 3 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST |
4 | .union(paths::PATH_FIRST) | 4 | .union(paths::PATH_FIRST) |
5 | .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS]); | 5 | .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS, DOT]); |
6 | 6 | ||
7 | pub(crate) fn pattern(p: &mut Parser) { | 7 | pub(crate) fn pattern(p: &mut Parser) { |
8 | pattern_r(p, PAT_RECOVERY_SET); | 8 | pattern_r(p, PAT_RECOVERY_SET); |
@@ -73,6 +73,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | |||
73 | _ if paths::is_use_path_start(p) => path_pat(p), | 73 | _ if paths::is_use_path_start(p) => path_pat(p), |
74 | _ if is_literal_pat_start(p) => literal_pat(p), | 74 | _ if is_literal_pat_start(p) => literal_pat(p), |
75 | 75 | ||
76 | T![.] if p.at(T![..]) => dot_dot_pat(p), | ||
76 | T![_] => placeholder_pat(p), | 77 | T![_] => placeholder_pat(p), |
77 | T![&] => ref_pat(p), | 78 | T![&] => ref_pat(p), |
78 | T!['('] => tuple_pat(p), | 79 | T!['('] => tuple_pat(p), |
@@ -163,7 +164,9 @@ fn record_field_pat_list(p: &mut Parser) { | |||
163 | p.bump_any(); | 164 | p.bump_any(); |
164 | while !p.at(EOF) && !p.at(T!['}']) { | 165 | while !p.at(EOF) && !p.at(T!['}']) { |
165 | match p.current() { | 166 | match p.current() { |
167 | // A trailing `..` is *not* treated as a DOT_DOT_PAT. | ||
166 | T![.] if p.at(T![..]) => p.bump(T![..]), | 168 | T![.] if p.at(T![..]) => p.bump(T![..]), |
169 | |||
167 | IDENT if p.nth(1) == T![:] => record_field_pat(p), | 170 | IDENT if p.nth(1) == T![:] => record_field_pat(p), |
168 | T!['{'] => error_block(p, "expected ident"), | 171 | T!['{'] => error_block(p, "expected ident"), |
169 | T![box] => { | 172 | T![box] => { |
@@ -201,6 +204,39 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker { | |||
201 | m.complete(p, PLACEHOLDER_PAT) | 204 | m.complete(p, PLACEHOLDER_PAT) |
202 | } | 205 | } |
203 | 206 | ||
207 | // test dot_dot_pat | ||
208 | // fn main() { | ||
209 | // let .. = (); | ||
210 | // // | ||
211 | // // Tuples | ||
212 | // // | ||
213 | // let (a, ..) = (); | ||
214 | // let (a, ..,) = (); | ||
215 | // let Tuple(a, ..) = (); | ||
216 | // let Tuple(a, ..,) = (); | ||
217 | // let (.., ..) = (); | ||
218 | // let Tuple(.., ..) = (); | ||
219 | // let (.., a, ..) = (); | ||
220 | // let Tuple(.., a, ..) = (); | ||
221 | // // | ||
222 | // // Slices | ||
223 | // // | ||
224 | // let [..] = (); | ||
225 | // let [head, ..] = (); | ||
226 | // let [head, tail @ ..] = (); | ||
227 | // let [head, .., cons] = (); | ||
228 | // let [head, mid @ .., cons] = (); | ||
229 | // let [head, .., .., cons] = (); | ||
230 | // let [head, .., mid, tail @ ..] = (); | ||
231 | // let [head, .., mid, .., cons] = (); | ||
232 | // } | ||
233 | fn dot_dot_pat(p: &mut Parser) -> CompletedMarker { | ||
234 | assert!(p.at(T![..])); | ||
235 | let m = p.start(); | ||
236 | p.bump(T![..]); | ||
237 | m.complete(p, DOT_DOT_PAT) | ||
238 | } | ||
239 | |||
204 | // test ref_pat | 240 | // test ref_pat |
205 | // fn main() { | 241 | // fn main() { |
206 | // let &a = (); | 242 | // let &a = (); |
@@ -241,16 +277,12 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker { | |||
241 | 277 | ||
242 | fn pat_list(p: &mut Parser, ket: SyntaxKind) { | 278 | fn pat_list(p: &mut Parser, ket: SyntaxKind) { |
243 | while !p.at(EOF) && !p.at(ket) { | 279 | while !p.at(EOF) && !p.at(ket) { |
244 | match p.current() { | 280 | if !p.at_ts(PATTERN_FIRST) { |
245 | T![.] if p.at(T![..]) => p.bump(T![..]), | 281 | p.error("expected a pattern"); |
246 | _ => { | 282 | break; |
247 | if !p.at_ts(PATTERN_FIRST) { | ||
248 | p.error("expected a pattern"); | ||
249 | break; | ||
250 | } | ||
251 | pattern(p) | ||
252 | } | ||
253 | } | 283 | } |
284 | |||
285 | pattern(p); | ||
254 | if !p.at(ket) { | 286 | if !p.at(ket) { |
255 | p.expect(T![,]); | 287 | p.expect(T![,]); |
256 | } | 288 | } |