Skip to content

Commit 661fbd2

Browse files
Parse BoxPat
1 parent 4c69950 commit 661fbd2

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

crates/ra_parser/src/grammar/patterns.rs

+40-19
Original file line numberDiff line numberDiff line change
@@ -56,37 +56,34 @@ const PAT_RECOVERY_SET: TokenSet =
5656
token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA];
5757

5858
fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
59-
let la0 = p.nth(0);
60-
let la1 = p.nth(1);
61-
if la0 == T![ref]
62-
|| la0 == T![mut]
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-
}
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 = |la1| {
62+
la1 == T![::] || la1 == T!['('] || la1 == T!['{'] || la1 == T![!]
63+
};
7164

72-
if is_literal_pat_start(p) {
73-
return Some(literal_pat(p));
74-
}
65+
let m = match p.nth(0) {
66+
T![box] => box_pat(p),
67+
T![ref] | T![mut] | IDENT if !is_path_or_macro_pat(p.nth(1)) => bind_pat(p, true),
68+
69+
_ if paths::is_use_path_start(p) => path_pat(p),
70+
_ if is_literal_pat_start(p) => literal_pat(p),
7571

76-
let m = match la0 {
7772
T![_] => placeholder_pat(p),
7873
T![&] => ref_pat(p),
7974
T!['('] => tuple_pat(p),
8075
T!['['] => slice_pat(p),
76+
8177
_ => {
8278
p.err_recover("expected pattern", recovery_set);
8379
return None;
8480
}
8581
};
82+
8683
Some(m)
8784
}
8885

89-
fn is_literal_pat_start(p: &mut Parser) -> bool {
86+
fn is_literal_pat_start(p: &Parser) -> bool {
9087
p.at(T![-]) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER)
9188
|| p.at_ts(expressions::LITERAL_FIRST)
9289
}
@@ -261,11 +258,9 @@ fn pat_list(p: &mut Parser, ket: SyntaxKind) {
261258
// let ref mut d = ();
262259
// let e @ _ = ();
263260
// let ref mut f @ g @ _ = ();
264-
// let box i = Box::new(1i32);
265261
// }
266262
fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
267263
let m = p.start();
268-
p.eat(T![box]);
269264
p.eat(T![ref]);
270265
p.eat(T![mut]);
271266
name(p);
@@ -274,3 +269,29 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
274269
}
275270
m.complete(p, BIND_PAT)
276271
}
272+
273+
// test_err ref_box_pat
274+
// fn main() {
275+
// let ref box i = ();
276+
// }
277+
278+
// test box_pat
279+
// struct Outer<'a> {
280+
// i: Box<i32>,
281+
// j: Box<Inner<'a>>,
282+
// }
283+
//
284+
// struct Inner<'a>(&'a i32);
285+
//
286+
// fn main() {
287+
// let box i = ();
288+
// let box Outer { box i, j: box Inner(box &x) } = ();
289+
// let box ref mut i = ();
290+
// }
291+
fn box_pat(p: &mut Parser) -> CompletedMarker {
292+
assert!(p.at(T![box]));
293+
let m = p.start();
294+
p.bump();
295+
pattern(p);
296+
m.complete(p, BOX_PAT)
297+
}

crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ fn main() {
55
let ref mut d = ();
66
let e @ _ = ();
77
let ref mut f @ g @ _ = ();
8-
let box i = Box::new(1i32);
98
}

0 commit comments

Comments
 (0)