• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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