diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-25 10:47:44 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-08-25 10:47:44 +0100 |
commit | 866b41ddd86cbe9c3e8d9cb2896477bab060a044 (patch) | |
tree | 2108601228076d62e833b732de52e182b8be4a0b /crates/ra_parser/src | |
parent | fdece911fe8e2f3c22760ea22038a6d00cb70dfa (diff) | |
parent | c93903e9c7f64be2edcae0dfe62d8390514658b1 (diff) |
Merge #1733
1733: Parse arbitrarily complex `box` patterns. r=matklad a=ecstatic-morse
This fully resolves the pattern part of #1412 by enabling the parsing of complex `box` patterns such as:
```rust
let box Struct { box i, j: box Inner(box &x) } = todo!();
```
This introduces a new `ast::BoxPat` (in the mold of `ast::RefPat`) that gets translated to `hir::Pat::Missing`.
Co-authored-by: Dylan MacKenzie <[email protected]>
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 49 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 1 |
3 files changed, 31 insertions, 21 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index ab8fb9f6e..bc942ae01 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -414,8 +414,6 @@ pub(crate) fn match_arm_list(p: &mut Parser) { | |||
414 | // X | Y if Z => (), | 414 | // X | Y if Z => (), |
415 | // | X | Y if Z => (), | 415 | // | X | Y if Z => (), |
416 | // | X => (), | 416 | // | X => (), |
417 | // box X => (), | ||
418 | // Some(box X) => (), | ||
419 | // }; | 417 | // }; |
420 | // } | 418 | // } |
421 | fn match_arm(p: &mut Parser) -> BlockLike { | 419 | fn match_arm(p: &mut Parser) -> BlockLike { |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 8979aa499..eae70ab85 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -56,37 +56,33 @@ const PAT_RECOVERY_SET: TokenSet = | |||
56 | token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; | 56 | token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; |
57 | 57 | ||
58 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | 58 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { |
59 | let la0 = p.nth(0); | 59 | // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro |
60 | let la1 = p.nth(1); | 60 | // (T![x]). |
61 | if la0 == T![ref] | 61 | let is_path_or_macro_pat = |
62 | || la0 == T![mut] | 62 | |la1| la1 == T![::] || la1 == T!['('] || la1 == T!['{'] || la1 == T![!]; |
63 | || la0 == T![box] | ||
64 | || (la0 == IDENT && !(la1 == T![::] || la1 == T!['('] || la1 == T!['{'] || la1 == T![!])) | ||
65 | { | ||
66 | return Some(bind_pat(p, true)); | ||
67 | } | ||
68 | if paths::is_use_path_start(p) { | ||
69 | return Some(path_pat(p)); | ||
70 | } | ||
71 | 63 | ||
72 | if is_literal_pat_start(p) { | 64 | let m = match p.nth(0) { |
73 | return Some(literal_pat(p)); | 65 | T![box] => box_pat(p), |
74 | } | 66 | T![ref] | T![mut] | IDENT if !is_path_or_macro_pat(p.nth(1)) => bind_pat(p, true), |
67 | |||
68 | _ if paths::is_use_path_start(p) => path_pat(p), | ||
69 | _ if is_literal_pat_start(p) => literal_pat(p), | ||
75 | 70 | ||
76 | let m = match la0 { | ||
77 | T![_] => placeholder_pat(p), | 71 | T![_] => placeholder_pat(p), |
78 | T![&] => ref_pat(p), | 72 | T![&] => ref_pat(p), |
79 | T!['('] => tuple_pat(p), | 73 | T!['('] => tuple_pat(p), |
80 | T!['['] => slice_pat(p), | 74 | T!['['] => slice_pat(p), |
75 | |||
81 | _ => { | 76 | _ => { |
82 | p.err_recover("expected pattern", recovery_set); | 77 | p.err_recover("expected pattern", recovery_set); |
83 | return None; | 78 | return None; |
84 | } | 79 | } |
85 | }; | 80 | }; |
81 | |||
86 | Some(m) | 82 | Some(m) |
87 | } | 83 | } |
88 | 84 | ||
89 | fn is_literal_pat_start(p: &mut Parser) -> bool { | 85 | fn is_literal_pat_start(p: &Parser) -> bool { |
90 | p.at(T![-]) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) | 86 | p.at(T![-]) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) |
91 | || p.at_ts(expressions::LITERAL_FIRST) | 87 | || p.at_ts(expressions::LITERAL_FIRST) |
92 | } | 88 | } |
@@ -165,6 +161,9 @@ fn record_field_pat_list(p: &mut Parser) { | |||
165 | T![..] => p.bump(), | 161 | T![..] => p.bump(), |
166 | IDENT if p.nth(1) == T![:] => record_field_pat(p), | 162 | IDENT if p.nth(1) == T![:] => record_field_pat(p), |
167 | T!['{'] => error_block(p, "expected ident"), | 163 | T!['{'] => error_block(p, "expected ident"), |
164 | T![box] => { | ||
165 | box_pat(p); | ||
166 | } | ||
168 | _ => { | 167 | _ => { |
169 | bind_pat(p, false); | 168 | bind_pat(p, false); |
170 | } | 169 | } |
@@ -261,11 +260,9 @@ fn pat_list(p: &mut Parser, ket: SyntaxKind) { | |||
261 | // let ref mut d = (); | 260 | // let ref mut d = (); |
262 | // let e @ _ = (); | 261 | // let e @ _ = (); |
263 | // let ref mut f @ g @ _ = (); | 262 | // let ref mut f @ g @ _ = (); |
264 | // let box i = Box::new(1i32); | ||
265 | // } | 263 | // } |
266 | fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { | 264 | fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { |
267 | let m = p.start(); | 265 | let m = p.start(); |
268 | p.eat(T![box]); | ||
269 | p.eat(T![ref]); | 266 | p.eat(T![ref]); |
270 | p.eat(T![mut]); | 267 | p.eat(T![mut]); |
271 | name(p); | 268 | name(p); |
@@ -274,3 +271,17 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { | |||
274 | } | 271 | } |
275 | m.complete(p, BIND_PAT) | 272 | m.complete(p, BIND_PAT) |
276 | } | 273 | } |
274 | |||
275 | // test box_pat | ||
276 | // fn main() { | ||
277 | // let box i = (); | ||
278 | // let box Outer { box i, j: box Inner(box &x) } = (); | ||
279 | // let box ref mut i = (); | ||
280 | // } | ||
281 | fn box_pat(p: &mut Parser) -> CompletedMarker { | ||
282 | assert!(p.at(T![box])); | ||
283 | let m = p.start(); | ||
284 | p.bump(); | ||
285 | pattern(p); | ||
286 | m.complete(p, BOX_PAT) | ||
287 | } | ||
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index f15e98e68..8ba29ebf8 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -149,6 +149,7 @@ pub enum SyntaxKind { | |||
149 | IMPL_TRAIT_TYPE, | 149 | IMPL_TRAIT_TYPE, |
150 | DYN_TRAIT_TYPE, | 150 | DYN_TRAIT_TYPE, |
151 | REF_PAT, | 151 | REF_PAT, |
152 | BOX_PAT, | ||
152 | BIND_PAT, | 153 | BIND_PAT, |
153 | PLACEHOLDER_PAT, | 154 | PLACEHOLDER_PAT, |
154 | PATH_PAT, | 155 | PATH_PAT, |