7 // fn d(x: i32, y: ()) {}
8 pub(super) fn param_list_fn_def(p: &mut Parser) {
9 list_(p, Flavor::FnDef)
12 // test param_list_opt_patterns
13 // fn foo<F: FnMut(&mut Foo<'a>)>(){}
14 pub(super) fn param_list_fn_trait(p: &mut Parser) {
15 list_(p, Flavor::FnTrait)
18 pub(super) fn param_list_fn_ptr(p: &mut Parser) {
19 list_(p, Flavor::FnPointer)
22 pub(super) fn param_list_closure(p: &mut Parser) {
23 list_(p, Flavor::Closure)
26 #[derive(Debug, Clone, Copy)]
28 FnDef, // Includes trait fn params; omitted param idents are not supported
29 FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
34 fn list_(p: &mut Parser, flavor: Flavor) {
37 let (bra, ket) = match flavor {
38 Closure => (T![|], T![|]),
39 FnDef | FnTrait | FnPointer => (T!['('], T![')']),
42 let list_marker = p.start();
45 let mut param_marker = None;
46 if let FnDef = flavor {
47 // test self_param_outer_attr
48 // fn f(#[must_use] self) {}
50 attributes::outer_attrs(p);
51 match opt_self_param(p, m) {
53 Err(m) => param_marker = Some(m),
57 while !p.at(EOF) && !p.at(ket) {
58 // test param_outer_arg
59 // fn f(#[attr1] pat: Type) {}
60 let m = match param_marker.take() {
64 attributes::outer_attrs(p);
69 if !p.at_ts(PARAM_FIRST) {
70 p.error("expected value parameter");
74 let param = param(p, m, flavor);
78 if let Variadic(true) = param {
83 if let Some(m) = param_marker {
88 list_marker.complete(p, PARAM_LIST);
91 const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
93 struct Variadic(bool);
95 fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
96 let mut res = Variadic(false);
98 // test param_list_vararg
99 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
100 Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
103 // fn foo((x, y): (i32, i32)) {}
105 patterns::pattern(p);
106 if variadic_param(p) {
109 types::ascription(p);
112 // test value_parameters_no_patterns
113 // type F = Box<Fn(i32, &i32, &i32, ())>;
117 // test fn_pointer_param_ident_path
118 // type Foo = fn(Bar::Baz);
119 // type Qux = fn(baz: Bar::Baz);
121 // test fn_pointer_unnamed_arg
122 // type Foo = fn(_: bar);
123 Flavor::FnPointer => {
124 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
125 patterns::pattern_single(p);
126 if variadic_param(p) {
129 types::ascription(p);
135 // test closure_params
137 // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
140 patterns::pattern_single(p);
141 if p.at(T![:]) && !p.at(T![::]) {
142 types::ascription(p);
146 m.complete(p, PARAM);
150 fn variadic_param(p: &mut Parser) -> bool {
151 if p.at(T![:]) && p.nth_at(1, T![...]) {
164 // fn c(&'a self,) {}
165 // fn d(&'a mut self, x: i32) {}
168 fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> {
169 if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] {
172 // test arb_self_types
174 // fn a(self: &Self) {}
175 // fn b(mut self: Box<Self>) {}
178 types::ascription(p);
185 (p.current(), la1, la2, la3),
186 (T![&], T![self], _, _)
187 | (T![&], T![mut], T![self], _)
188 | (T![&], LIFETIME_IDENT, T![self], _)
189 | (T![&], LIFETIME_IDENT, T![mut], T![self])
194 if p.at(LIFETIME_IDENT) {
200 m.complete(p, SELF_PARAM);
207 fn self_as_name(p: &mut Parser) {