1 use crate::grammar::attributes::ATTRIBUTE_FIRST;
2
3 use super::*;
4
5 // test param_list
6 // fn a() {}
7 // fn b(x: i32) {}
8 // fn c(x: i32, ) {}
9 // fn d(x: i32, y: ()) {}
param_list_fn_def(p: &mut Parser<'_>)10 pub(super) fn param_list_fn_def(p: &mut Parser<'_>) {
11 list_(p, Flavor::FnDef);
12 }
13
14 // test param_list_opt_patterns
15 // fn foo<F: FnMut(&mut Foo<'a>)>(){}
param_list_fn_trait(p: &mut Parser<'_>)16 pub(super) fn param_list_fn_trait(p: &mut Parser<'_>) {
17 list_(p, Flavor::FnTrait);
18 }
19
param_list_fn_ptr(p: &mut Parser<'_>)20 pub(super) fn param_list_fn_ptr(p: &mut Parser<'_>) {
21 list_(p, Flavor::FnPointer);
22 }
23
param_list_closure(p: &mut Parser<'_>)24 pub(super) fn param_list_closure(p: &mut Parser<'_>) {
25 list_(p, Flavor::Closure);
26 }
27
28 #[derive(Debug, Clone, Copy)]
29 enum Flavor {
30 FnDef, // Includes trait fn params; omitted param idents are not supported
31 FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
32 FnPointer,
33 Closure,
34 }
35
list_(p: &mut Parser<'_>, flavor: Flavor)36 fn list_(p: &mut Parser<'_>, flavor: Flavor) {
37 use Flavor::*;
38
39 let (bra, ket) = match flavor {
40 Closure => (T![|], T![|]),
41 FnDef | FnTrait | FnPointer => (T!['('], T![')']),
42 };
43
44 let list_marker = p.start();
45 p.bump(bra);
46
47 let mut param_marker = None;
48 if let FnDef = flavor {
49 // test self_param_outer_attr
50 // fn f(#[must_use] self) {}
51 let m = p.start();
52 attributes::outer_attrs(p);
53 match opt_self_param(p, m) {
54 Ok(()) => {}
55 Err(m) => param_marker = Some(m),
56 }
57 }
58
59 while !p.at(EOF) && !p.at(ket) {
60 // test param_outer_arg
61 // fn f(#[attr1] pat: Type) {}
62 let m = match param_marker.take() {
63 Some(m) => m,
64 None => {
65 let m = p.start();
66 attributes::outer_attrs(p);
67 m
68 }
69 };
70
71 if !p.at_ts(PARAM_FIRST.union(ATTRIBUTE_FIRST)) {
72 p.error("expected value parameter");
73 m.abandon(p);
74 break;
75 }
76 param(p, m, flavor);
77 if !p.at(T![,]) {
78 if p.at_ts(PARAM_FIRST.union(ATTRIBUTE_FIRST)) {
79 p.error("expected `,`");
80 } else {
81 break;
82 }
83 } else {
84 p.bump(T![,]);
85 }
86 }
87
88 if let Some(m) = param_marker {
89 m.abandon(p);
90 }
91
92 p.expect(ket);
93 list_marker.complete(p, PARAM_LIST);
94 }
95
96 const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
97
param(p: &mut Parser<'_>, m: Marker, flavor: Flavor)98 fn param(p: &mut Parser<'_>, m: Marker, flavor: Flavor) {
99 match flavor {
100 // test param_list_vararg
101 // extern "C" { fn printf(format: *const i8, ..., _: u8) -> i32; }
102 Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => {}
103
104 // test fn_def_param
105 // fn foo(..., (x, y): (i32, i32)) {}
106 Flavor::FnDef => {
107 patterns::pattern(p);
108 if !variadic_param(p) {
109 if p.at(T![:]) {
110 types::ascription(p);
111 } else {
112 // test_err missing_fn_param_type
113 // fn f(x y: i32, z, t: i32) {}
114 p.error("missing type for function parameter");
115 }
116 }
117 }
118 // test value_parameters_no_patterns
119 // type F = Box<Fn(i32, &i32, &i32, ())>;
120 Flavor::FnTrait => {
121 types::type_(p);
122 }
123 // test fn_pointer_param_ident_path
124 // type Foo = fn(Bar::Baz);
125 // type Qux = fn(baz: Bar::Baz);
126
127 // test fn_pointer_unnamed_arg
128 // type Foo = fn(_: bar);
129 Flavor::FnPointer => {
130 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
131 patterns::pattern_single(p);
132 if !variadic_param(p) {
133 if p.at(T![:]) {
134 types::ascription(p);
135 } else {
136 p.error("missing type for function parameter");
137 }
138 }
139 } else {
140 types::type_(p);
141 }
142 }
143 // test closure_params
144 // fn main() {
145 // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
146 // }
147 Flavor::Closure => {
148 patterns::pattern_single(p);
149 if p.at(T![:]) && !p.at(T![::]) {
150 types::ascription(p);
151 }
152 }
153 }
154 m.complete(p, PARAM);
155 }
156
variadic_param(p: &mut Parser<'_>) -> bool157 fn variadic_param(p: &mut Parser<'_>) -> bool {
158 if p.at(T![:]) && p.nth_at(1, T![...]) {
159 p.bump(T![:]);
160 p.bump(T![...]);
161 true
162 } else {
163 false
164 }
165 }
166
167 // test self_param
168 // impl S {
169 // fn a(self) {}
170 // fn b(&self,) {}
171 // fn c(&'a self,) {}
172 // fn d(&'a mut self, x: i32) {}
173 // fn e(mut self) {}
174 // }
opt_self_param(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker>175 fn opt_self_param(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
176 if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] {
177 p.eat(T![mut]);
178 self_as_name(p);
179 // test arb_self_types
180 // impl S {
181 // fn a(self: &Self) {}
182 // fn b(mut self: Box<Self>) {}
183 // }
184 if p.at(T![:]) {
185 types::ascription(p);
186 }
187 } else {
188 let la1 = p.nth(1);
189 let la2 = p.nth(2);
190 let la3 = p.nth(3);
191 if !matches!(
192 (p.current(), la1, la2, la3),
193 (T![&], T![self], _, _)
194 | (T![&], T![mut] | LIFETIME_IDENT, T![self], _)
195 | (T![&], LIFETIME_IDENT, T![mut], T![self])
196 ) {
197 return Err(m);
198 }
199 p.bump(T![&]);
200 if p.at(LIFETIME_IDENT) {
201 lifetime(p);
202 }
203 p.eat(T![mut]);
204 self_as_name(p);
205 }
206 m.complete(p, SELF_PARAM);
207 if !p.at(T![')']) {
208 p.expect(T![,]);
209 }
210 Ok(())
211 }
212
self_as_name(p: &mut Parser<'_>)213 fn self_as_name(p: &mut Parser<'_>) {
214 let m = p.start();
215 p.bump(T![self]);
216 m.complete(p, NAME);
217 }
218