diff options
Diffstat (limited to 'src/grammar')
-rw-r--r-- | src/grammar/params.rs | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/src/grammar/params.rs b/src/grammar/params.rs index 034542df1..c7f17168b 100644 --- a/src/grammar/params.rs +++ b/src/grammar/params.rs | |||
@@ -6,35 +6,67 @@ use super::*; | |||
6 | // fn c(x: i32, ) {} | 6 | // fn c(x: i32, ) {} |
7 | // fn d(x: i32, y: ()) {} | 7 | // fn d(x: i32, y: ()) {} |
8 | pub(super) fn param_list(p: &mut Parser) { | 8 | pub(super) fn param_list(p: &mut Parser) { |
9 | list_(p, true) | 9 | list_(p, Flavor::Normal) |
10 | } | ||
11 | |||
12 | // test param_list_opt_patterns | ||
13 | // fn foo<F: FnMut(&mut Foo<'a>)>(){} | ||
14 | pub(super) fn param_list_opt_patterns(p: &mut Parser) { | ||
15 | list_(p, Flavor::OptionalPattern) | ||
10 | } | 16 | } |
11 | 17 | ||
12 | pub(super) fn param_list_opt_types(p: &mut Parser) { | 18 | pub(super) fn param_list_opt_types(p: &mut Parser) { |
13 | list_(p, false) | 19 | list_(p, Flavor::OptionalType) |
20 | } | ||
21 | |||
22 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
23 | enum Flavor { | ||
24 | OptionalType, | ||
25 | OptionalPattern, | ||
26 | Normal, | ||
14 | } | 27 | } |
15 | 28 | ||
16 | fn list_(p: &mut Parser, require_types: bool) { | 29 | impl Flavor { |
17 | assert!(p.at(if require_types { L_PAREN } else { PIPE })); | 30 | fn type_required(self) -> bool { |
31 | match self { | ||
32 | Flavor::OptionalType => false, | ||
33 | _ => true, | ||
34 | } | ||
35 | } | ||
36 | fn pattern_required(self) -> bool { | ||
37 | match self { | ||
38 | Flavor::OptionalPattern => false, | ||
39 | _ => true, | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
44 | fn list_(p: &mut Parser, flavor: Flavor) { | ||
45 | let (bra, ket) = if flavor.type_required() { | ||
46 | (L_PAREN, R_PAREN) | ||
47 | } else { | ||
48 | (PIPE, PIPE) | ||
49 | }; | ||
50 | assert!(p.at(bra)); | ||
18 | let m = p.start(); | 51 | let m = p.start(); |
19 | p.bump(); | 52 | p.bump(); |
20 | if require_types { | 53 | if flavor.type_required() { |
21 | self_param(p); | 54 | self_param(p); |
22 | } | 55 | } |
23 | let terminator = if require_types { R_PAREN } else { PIPE }; | 56 | while !p.at(EOF) && !p.at(ket) { |
24 | while !p.at(EOF) && !p.at(terminator) { | 57 | value_parameter(p, flavor); |
25 | value_parameter(p, require_types); | 58 | if !p.at(ket) { |
26 | if !p.at(terminator) { | ||
27 | p.expect(COMMA); | 59 | p.expect(COMMA); |
28 | } | 60 | } |
29 | } | 61 | } |
30 | p.expect(terminator); | 62 | p.expect(ket); |
31 | m.complete(p, PARAM_LIST); | 63 | m.complete(p, PARAM_LIST); |
32 | } | 64 | } |
33 | 65 | ||
34 | fn value_parameter(p: &mut Parser, require_type: bool) { | 66 | fn value_parameter(p: &mut Parser, flavor: Flavor) { |
35 | let m = p.start(); | 67 | let m = p.start(); |
36 | patterns::pattern(p); | 68 | patterns::pattern(p); |
37 | if p.at(COLON) || require_type { | 69 | if p.at(COLON) || flavor.type_required() { |
38 | types::ascription(p) | 70 | types::ascription(p) |
39 | } | 71 | } |
40 | m.complete(p, PARAM); | 72 | m.complete(p, PARAM); |