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/expressions/atom.rs4
-rw-r--r--crates/ra_parser/src/grammar/params.rs4
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs66
3 files changed, 60 insertions, 14 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index f154077a8..b72d2e9e6 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -336,7 +336,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
336fn cond(p: &mut Parser) { 336fn cond(p: &mut Parser) {
337 let m = p.start(); 337 let m = p.start();
338 if p.eat(T![let]) { 338 if p.eat(T![let]) {
339 patterns::pattern_list(p); 339 patterns::pattern_top(p);
340 p.expect(T![=]); 340 p.expect(T![=]);
341 } 341 }
342 expr_no_struct(p); 342 expr_no_struct(p);
@@ -430,7 +430,7 @@ fn match_arm(p: &mut Parser) -> BlockLike {
430 // } 430 // }
431 attributes::outer_attributes(p); 431 attributes::outer_attributes(p);
432 432
433 patterns::pattern_list_r(p, TokenSet::EMPTY); 433 patterns::pattern_top_r(p, TokenSet::EMPTY);
434 if p.at(T![if]) { 434 if p.at(T![if]) {
435 match_guard(p); 435 match_guard(p);
436 } 436 }
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index 94edc7f35..ed4f93347 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -116,7 +116,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
116 // type Qux = fn(baz: Bar::Baz); 116 // type Qux = fn(baz: Bar::Baz);
117 Flavor::FnPointer => { 117 Flavor::FnPointer => {
118 if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { 118 if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
119 patterns::pattern(p); 119 patterns::pattern_single(p);
120 types::ascription(p); 120 types::ascription(p);
121 } else { 121 } else {
122 types::type_(p); 122 types::type_(p);
@@ -127,7 +127,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
127 // let foo = |bar, baz: Baz, qux: Qux::Quux| (); 127 // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
128 // } 128 // }
129 Flavor::Closure => { 129 Flavor::Closure => {
130 patterns::pattern(p); 130 patterns::pattern_single(p);
131 if p.at(T![:]) && !p.at(T![::]) { 131 if p.at(T![:]) && !p.at(T![::]) {
132 types::ascription(p); 132 types::ascription(p);
133 } 133 }
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 422a4e3dc..c6a2e4d39 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -11,22 +11,49 @@ pub(crate) fn pattern(p: &mut Parser) {
11} 11}
12 12
13/// Parses a pattern list separated by pipes `|` 13/// Parses a pattern list separated by pipes `|`
14pub(super) fn pattern_list(p: &mut Parser) { 14pub(super) fn pattern_top(p: &mut Parser) {
15 pattern_list_r(p, PAT_RECOVERY_SET) 15 pattern_top_r(p, PAT_RECOVERY_SET)
16}
17
18pub(crate) fn pattern_single(p: &mut Parser) {
19 pattern_single_r(p, PAT_RECOVERY_SET);
16} 20}
17 21
18/// Parses a pattern list separated by pipes `|` 22/// Parses a pattern list separated by pipes `|`
19/// using the given `recovery_set` 23/// using the given `recovery_set`
20pub(super) fn pattern_list_r(p: &mut Parser, recovery_set: TokenSet) { 24pub(super) fn pattern_top_r(p: &mut Parser, recovery_set: TokenSet) {
21 p.eat(T![|]); 25 p.eat(T![|]);
22 pattern_r(p, recovery_set); 26 pattern_r(p, recovery_set);
27}
23 28
29/// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
30/// given `recovery_set`
31// test or_pattern
32// fn main() {
33// match () {
34// (_ | _) => (),
35// &(_ | _) => (),
36// (_ | _,) => (),
37// [_ | _,] => (),
38// }
39// }
40fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
41 let m = p.start();
42 pattern_single_r(p, recovery_set);
43
44 let mut is_or_pat = false;
24 while p.eat(T![|]) { 45 while p.eat(T![|]) {
25 pattern_r(p, recovery_set); 46 is_or_pat = true;
47 pattern_single_r(p, recovery_set);
48 }
49 if is_or_pat {
50 m.complete(p, OR_PAT);
51 } else {
52 m.abandon(p);
26 } 53 }
27} 54}
28 55
29pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { 56fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
30 if let Some(lhs) = atom_pat(p, recovery_set) { 57 if let Some(lhs) = atom_pat(p, recovery_set) {
31 // test range_pat 58 // test range_pat
32 // fn main() { 59 // fn main() {
@@ -258,7 +285,7 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker {
258 let m = p.start(); 285 let m = p.start();
259 p.bump(T![&]); 286 p.bump(T![&]);
260 p.eat(T![mut]); 287 p.eat(T![mut]);
261 pattern(p); 288 pattern_single(p);
262 m.complete(p, REF_PAT) 289 m.complete(p, REF_PAT)
263} 290}
264 291
@@ -269,8 +296,27 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker {
269fn tuple_pat(p: &mut Parser) -> CompletedMarker { 296fn tuple_pat(p: &mut Parser) -> CompletedMarker {
270 assert!(p.at(T!['('])); 297 assert!(p.at(T!['(']));
271 let m = p.start(); 298 let m = p.start();
272 tuple_pat_fields(p); 299 p.bump(T!['(']);
273 m.complete(p, TUPLE_PAT) 300 let mut has_comma = false;
301 let mut has_pat = false;
302 let mut has_rest = false;
303 while !p.at(EOF) && !p.at(T![')']) {
304 has_pat = true;
305 if !p.at_ts(PATTERN_FIRST) {
306 p.error("expected a pattern");
307 break;
308 }
309 has_rest |= p.at(T![..]);
310
311 pattern(p);
312 if !p.at(T![')']) {
313 has_comma = true;
314 p.expect(T![,]);
315 }
316 }
317 p.expect(T![')']);
318
319 m.complete(p, if !has_comma && !has_rest && has_pat { PAREN_PAT } else { TUPLE_PAT })
274} 320}
275 321
276// test slice_pat 322// test slice_pat
@@ -315,7 +361,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
315 p.eat(T![mut]); 361 p.eat(T![mut]);
316 name(p); 362 name(p);
317 if with_at && p.eat(T![@]) { 363 if with_at && p.eat(T![@]) {
318 pattern(p); 364 pattern_single(p);
319 } 365 }
320 m.complete(p, BIND_PAT) 366 m.complete(p, BIND_PAT)
321} 367}
@@ -330,6 +376,6 @@ fn box_pat(p: &mut Parser) -> CompletedMarker {
330 assert!(p.at(T![box])); 376 assert!(p.at(T![box]));
331 let m = p.start(); 377 let m = p.start();
332 p.bump(T![box]); 378 p.bump(T![box]);
333 pattern(p); 379 pattern_single(p);
334 m.complete(p, BOX_PAT) 380 m.complete(p, BOX_PAT)
335} 381}