aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar/params.rs56
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: ()) {}
8pub(super) fn param_list(p: &mut Parser) { 8pub(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>)>(){}
14pub(super) fn param_list_opt_patterns(p: &mut Parser) {
15 list_(p, Flavor::OptionalPattern)
10} 16}
11 17
12pub(super) fn param_list_opt_types(p: &mut Parser) { 18pub(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)]
23enum Flavor {
24 OptionalType,
25 OptionalPattern,
26 Normal,
14} 27}
15 28
16fn list_(p: &mut Parser, require_types: bool) { 29impl 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
44fn 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
34fn value_parameter(p: &mut Parser, require_type: bool) { 66fn 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);