diff options
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/params.rs | 9 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 67 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 2 |
4 files changed, 67 insertions, 15 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 { | |||
336 | fn cond(p: &mut Parser) { | 336 | fn 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..272661b1d 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs | |||
@@ -114,9 +114,12 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
114 | // test fn_pointer_param_ident_path | 114 | // test fn_pointer_param_ident_path |
115 | // type Foo = fn(Bar::Baz); | 115 | // type Foo = fn(Bar::Baz); |
116 | // type Qux = fn(baz: Bar::Baz); | 116 | // type Qux = fn(baz: Bar::Baz); |
117 | |||
118 | // test fn_pointer_unnamed_arg | ||
119 | // type Foo = fn(_: bar); | ||
117 | Flavor::FnPointer => { | 120 | Flavor::FnPointer => { |
118 | if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { | 121 | if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { |
119 | patterns::pattern(p); | 122 | patterns::pattern_single(p); |
120 | types::ascription(p); | 123 | types::ascription(p); |
121 | } else { | 124 | } else { |
122 | types::type_(p); | 125 | types::type_(p); |
@@ -127,7 +130,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
127 | // let foo = |bar, baz: Baz, qux: Qux::Quux| (); | 130 | // let foo = |bar, baz: Baz, qux: Qux::Quux| (); |
128 | // } | 131 | // } |
129 | Flavor::Closure => { | 132 | Flavor::Closure => { |
130 | patterns::pattern(p); | 133 | patterns::pattern_single(p); |
131 | if p.at(T![:]) && !p.at(T![::]) { | 134 | if p.at(T![:]) && !p.at(T![::]) { |
132 | types::ascription(p); | 135 | types::ascription(p); |
133 | } | 136 | } |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 422a4e3dc..3afbaa82b 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -11,22 +11,47 @@ 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 `|` |
14 | pub(super) fn pattern_list(p: &mut Parser) { | 14 | pub(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 | |||
18 | pub(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` |
20 | pub(super) fn pattern_list_r(p: &mut Parser, recovery_set: TokenSet) { | 24 | pub(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 | // } | ||
40 | fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { | ||
41 | let m = p.start(); | ||
42 | pattern_single_r(p, recovery_set); | ||
43 | |||
44 | if !p.at(T![|]) { | ||
45 | m.abandon(p); | ||
46 | return; | ||
47 | } | ||
24 | while p.eat(T![|]) { | 48 | while p.eat(T![|]) { |
25 | pattern_r(p, recovery_set); | 49 | pattern_single_r(p, recovery_set); |
26 | } | 50 | } |
51 | m.complete(p, OR_PAT); | ||
27 | } | 52 | } |
28 | 53 | ||
29 | pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { | 54 | fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) { |
30 | if let Some(lhs) = atom_pat(p, recovery_set) { | 55 | if let Some(lhs) = atom_pat(p, recovery_set) { |
31 | // test range_pat | 56 | // test range_pat |
32 | // fn main() { | 57 | // fn main() { |
@@ -258,19 +283,41 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker { | |||
258 | let m = p.start(); | 283 | let m = p.start(); |
259 | p.bump(T![&]); | 284 | p.bump(T![&]); |
260 | p.eat(T![mut]); | 285 | p.eat(T![mut]); |
261 | pattern(p); | 286 | pattern_single(p); |
262 | m.complete(p, REF_PAT) | 287 | m.complete(p, REF_PAT) |
263 | } | 288 | } |
264 | 289 | ||
265 | // test tuple_pat | 290 | // test tuple_pat |
266 | // fn main() { | 291 | // fn main() { |
267 | // let (a, b, ..) = (); | 292 | // let (a, b, ..) = (); |
293 | // let (a,) = (); | ||
294 | // let (..) = (); | ||
295 | // let () = (); | ||
268 | // } | 296 | // } |
269 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { | 297 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { |
270 | assert!(p.at(T!['('])); | 298 | assert!(p.at(T!['('])); |
271 | let m = p.start(); | 299 | let m = p.start(); |
272 | tuple_pat_fields(p); | 300 | p.bump(T!['(']); |
273 | m.complete(p, TUPLE_PAT) | 301 | let mut has_comma = false; |
302 | let mut has_pat = false; | ||
303 | let mut has_rest = false; | ||
304 | while !p.at(EOF) && !p.at(T![')']) { | ||
305 | has_pat = true; | ||
306 | if !p.at_ts(PATTERN_FIRST) { | ||
307 | p.error("expected a pattern"); | ||
308 | break; | ||
309 | } | ||
310 | has_rest |= p.at(T![..]); | ||
311 | |||
312 | pattern(p); | ||
313 | if !p.at(T![')']) { | ||
314 | has_comma = true; | ||
315 | p.expect(T![,]); | ||
316 | } | ||
317 | } | ||
318 | p.expect(T![')']); | ||
319 | |||
320 | m.complete(p, if !has_comma && !has_rest && has_pat { PAREN_PAT } else { TUPLE_PAT }) | ||
274 | } | 321 | } |
275 | 322 | ||
276 | // test slice_pat | 323 | // test slice_pat |
@@ -315,7 +362,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { | |||
315 | p.eat(T![mut]); | 362 | p.eat(T![mut]); |
316 | name(p); | 363 | name(p); |
317 | if with_at && p.eat(T![@]) { | 364 | if with_at && p.eat(T![@]) { |
318 | pattern(p); | 365 | pattern_single(p); |
319 | } | 366 | } |
320 | m.complete(p, BIND_PAT) | 367 | m.complete(p, BIND_PAT) |
321 | } | 368 | } |
@@ -330,6 +377,6 @@ fn box_pat(p: &mut Parser) -> CompletedMarker { | |||
330 | assert!(p.at(T![box])); | 377 | assert!(p.at(T![box])); |
331 | let m = p.start(); | 378 | let m = p.start(); |
332 | p.bump(T![box]); | 379 | p.bump(T![box]); |
333 | pattern(p); | 380 | pattern_single(p); |
334 | m.complete(p, BOX_PAT) | 381 | m.complete(p, BOX_PAT) |
335 | } | 382 | } |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index e27b27ffa..1068da0a0 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -151,6 +151,8 @@ pub enum SyntaxKind { | |||
151 | FOR_TYPE, | 151 | FOR_TYPE, |
152 | IMPL_TRAIT_TYPE, | 152 | IMPL_TRAIT_TYPE, |
153 | DYN_TRAIT_TYPE, | 153 | DYN_TRAIT_TYPE, |
154 | OR_PAT, | ||
155 | PAREN_PAT, | ||
154 | REF_PAT, | 156 | REF_PAT, |
155 | BOX_PAT, | 157 | BOX_PAT, |
156 | BIND_PAT, | 158 | BIND_PAT, |