aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-08-25 10:47:44 +0100
committerGitHub <[email protected]>2019-08-25 10:47:44 +0100
commit866b41ddd86cbe9c3e8d9cb2896477bab060a044 (patch)
tree2108601228076d62e833b732de52e182b8be4a0b /crates/ra_parser/src
parentfdece911fe8e2f3c22760ea22038a6d00cb70dfa (diff)
parentc93903e9c7f64be2edcae0dfe62d8390514658b1 (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.rs2
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs49
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs1
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// }
421fn match_arm(p: &mut Parser) -> BlockLike { 419fn 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
58fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { 58fn 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
89fn is_literal_pat_start(p: &mut Parser) -> bool { 85fn 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// }
266fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { 264fn 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// }
281fn 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,