aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs51
1 files changed, 32 insertions, 19 deletions
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 8979aa499..67f1548a7 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}
@@ -261,11 +257,9 @@ fn pat_list(p: &mut Parser, ket: SyntaxKind) {
261// let ref mut d = (); 257// let ref mut d = ();
262// let e @ _ = (); 258// let e @ _ = ();
263// let ref mut f @ g @ _ = (); 259// let ref mut f @ g @ _ = ();
264// let box i = Box::new(1i32);
265// } 260// }
266fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { 261fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
267 let m = p.start(); 262 let m = p.start();
268 p.eat(T![box]);
269 p.eat(T![ref]); 263 p.eat(T![ref]);
270 p.eat(T![mut]); 264 p.eat(T![mut]);
271 name(p); 265 name(p);
@@ -274,3 +268,22 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
274 } 268 }
275 m.complete(p, BIND_PAT) 269 m.complete(p, BIND_PAT)
276} 270}
271
272// test_err ref_box_pat
273// fn main() {
274// let ref box i = ();
275// }
276
277// test box_pat
278// fn main() {
279// let box i = ();
280// let box Outer { box i, j: box Inner(box &x) } = ();
281// let box ref mut i = ();
282// }
283fn box_pat(p: &mut Parser) -> CompletedMarker {
284 assert!(p.at(T![box]));
285 let m = p.start();
286 p.bump();
287 pattern(p);
288 m.complete(p, BOX_PAT)
289}