diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar/params.rs | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index 272661b1d..f0da173cc 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs | |||
@@ -56,21 +56,17 @@ fn list_(p: &mut Parser, flavor: Flavor) { | |||
56 | // fn f(#[attr1] pat: Type) {} | 56 | // fn f(#[attr1] pat: Type) {} |
57 | attributes::outer_attributes(p); | 57 | attributes::outer_attributes(p); |
58 | 58 | ||
59 | // test param_list_vararg | ||
60 | // extern "C" { fn printf(format: *const i8, ...) -> i32; } | ||
61 | match flavor { | ||
62 | FnDef | FnPointer if p.eat(T![...]) => break, | ||
63 | _ => (), | ||
64 | } | ||
65 | |||
66 | if !p.at_ts(VALUE_PARAMETER_FIRST) { | 59 | if !p.at_ts(VALUE_PARAMETER_FIRST) { |
67 | p.error("expected value parameter"); | 60 | p.error("expected value parameter"); |
68 | break; | 61 | break; |
69 | } | 62 | } |
70 | value_parameter(p, flavor); | 63 | let param = value_parameter(p, flavor); |
71 | if !p.at(ket) { | 64 | if !p.at(ket) { |
72 | p.expect(T![,]); | 65 | p.expect(T![,]); |
73 | } | 66 | } |
67 | if let Variadic(true) = param { | ||
68 | break; | ||
69 | } | ||
74 | } | 70 | } |
75 | 71 | ||
76 | p.expect(ket); | 72 | p.expect(ket); |
@@ -79,32 +75,25 @@ fn list_(p: &mut Parser, flavor: Flavor) { | |||
79 | 75 | ||
80 | const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); | 76 | const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); |
81 | 77 | ||
82 | fn value_parameter(p: &mut Parser, flavor: Flavor) { | 78 | struct Variadic(bool); |
79 | |||
80 | fn value_parameter(p: &mut Parser, flavor: Flavor) -> Variadic { | ||
81 | let mut res = Variadic(false); | ||
83 | let m = p.start(); | 82 | let m = p.start(); |
84 | match flavor { | 83 | match flavor { |
85 | // test trait_fn_placeholder_parameter | 84 | // test param_list_vararg |
86 | // trait Foo { | 85 | // extern "C" { fn printf(format: *const i8, ...) -> i32; } |
87 | // fn bar(_: u64, mut x: i32); | 86 | Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true), |
88 | // } | ||
89 | |||
90 | // test trait_fn_patterns | ||
91 | // trait T { | ||
92 | // fn f1((a, b): (usize, usize)) {} | ||
93 | // fn f2(S { a, b }: S) {} | ||
94 | // fn f3(NewType(a): NewType) {} | ||
95 | // fn f4(&&a: &&usize) {} | ||
96 | // } | ||
97 | 87 | ||
98 | // test fn_patterns | 88 | // test fn_def_param |
99 | // impl U { | 89 | // fn foo((x, y): (i32, i32)) {} |
100 | // fn f1((a, b): (usize, usize)) {} | ||
101 | // fn f2(S { a, b }: S) {} | ||
102 | // fn f3(NewType(a): NewType) {} | ||
103 | // fn f4(&&a: &&usize) {} | ||
104 | // } | ||
105 | Flavor::FnDef => { | 90 | Flavor::FnDef => { |
106 | patterns::pattern(p); | 91 | patterns::pattern(p); |
107 | types::ascription(p); | 92 | if variadic_param(p) { |
93 | res = Variadic(true) | ||
94 | } else { | ||
95 | types::ascription(p); | ||
96 | } | ||
108 | } | 97 | } |
109 | // test value_parameters_no_patterns | 98 | // test value_parameters_no_patterns |
110 | // type F = Box<Fn(i32, &i32, &i32, ())>; | 99 | // type F = Box<Fn(i32, &i32, &i32, ())>; |
@@ -120,7 +109,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
120 | Flavor::FnPointer => { | 109 | Flavor::FnPointer => { |
121 | if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { | 110 | if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { |
122 | patterns::pattern_single(p); | 111 | patterns::pattern_single(p); |
123 | types::ascription(p); | 112 | if variadic_param(p) { |
113 | res = Variadic(true) | ||
114 | } else { | ||
115 | types::ascription(p); | ||
116 | } | ||
124 | } else { | 117 | } else { |
125 | types::type_(p); | 118 | types::type_(p); |
126 | } | 119 | } |
@@ -137,6 +130,17 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
137 | } | 130 | } |
138 | } | 131 | } |
139 | m.complete(p, PARAM); | 132 | m.complete(p, PARAM); |
133 | res | ||
134 | } | ||
135 | |||
136 | fn variadic_param(p: &mut Parser) -> bool { | ||
137 | if p.at(T![:]) && p.nth_at(1, T![...]) { | ||
138 | p.bump(T![:]); | ||
139 | p.bump(T![...]); | ||
140 | true | ||
141 | } else { | ||
142 | false | ||
143 | } | ||
140 | } | 144 | } |
141 | 145 | ||
142 | // test self_param | 146 | // test self_param |