diff options
Diffstat (limited to 'crates/ra_parser/src/grammar/types.rs')
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs deleted file mode 100644 index 0aa173a52..000000000 --- a/crates/ra_parser/src/grammar/types.rs +++ /dev/null | |||
@@ -1,324 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use super::*; | ||
4 | |||
5 | pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![ | ||
6 | T!['('], | ||
7 | T!['['], | ||
8 | T![<], | ||
9 | T![!], | ||
10 | T![*], | ||
11 | T![&], | ||
12 | T![_], | ||
13 | T![fn], | ||
14 | T![unsafe], | ||
15 | T![extern], | ||
16 | T![for], | ||
17 | T![impl], | ||
18 | T![dyn], | ||
19 | ]); | ||
20 | |||
21 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA, L_DOLLAR]; | ||
22 | |||
23 | pub(crate) fn type_(p: &mut Parser) { | ||
24 | type_with_bounds_cond(p, true); | ||
25 | } | ||
26 | |||
27 | pub(super) fn type_no_bounds(p: &mut Parser) { | ||
28 | type_with_bounds_cond(p, false); | ||
29 | } | ||
30 | |||
31 | fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { | ||
32 | match p.current() { | ||
33 | T!['('] => paren_or_tuple_type(p), | ||
34 | T![!] => never_type(p), | ||
35 | T![*] => pointer_type(p), | ||
36 | T!['['] => array_or_slice_type(p), | ||
37 | T![&] => reference_type(p), | ||
38 | T![_] => placeholder_type(p), | ||
39 | T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p), | ||
40 | T![for] => for_type(p), | ||
41 | T![impl] => impl_trait_type(p), | ||
42 | T![dyn] => dyn_trait_type(p), | ||
43 | // Some path types are not allowed to have bounds (no plus) | ||
44 | T![<] => path_type_(p, allow_bounds), | ||
45 | _ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds), | ||
46 | _ => { | ||
47 | p.err_recover("expected type", TYPE_RECOVERY_SET); | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | pub(super) fn ascription(p: &mut Parser) { | ||
53 | p.expect(T![:]); | ||
54 | type_(p) | ||
55 | } | ||
56 | |||
57 | fn paren_or_tuple_type(p: &mut Parser) { | ||
58 | assert!(p.at(T!['('])); | ||
59 | let m = p.start(); | ||
60 | p.bump(T!['(']); | ||
61 | let mut n_types: u32 = 0; | ||
62 | let mut trailing_comma: bool = false; | ||
63 | while !p.at(EOF) && !p.at(T![')']) { | ||
64 | n_types += 1; | ||
65 | type_(p); | ||
66 | if p.eat(T![,]) { | ||
67 | trailing_comma = true; | ||
68 | } else { | ||
69 | trailing_comma = false; | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | p.expect(T![')']); | ||
74 | |||
75 | let kind = if n_types == 1 && !trailing_comma { | ||
76 | // test paren_type | ||
77 | // type T = (i32); | ||
78 | PAREN_TYPE | ||
79 | } else { | ||
80 | // test unit_type | ||
81 | // type T = (); | ||
82 | |||
83 | // test singleton_tuple_type | ||
84 | // type T = (i32,); | ||
85 | TUPLE_TYPE | ||
86 | }; | ||
87 | m.complete(p, kind); | ||
88 | } | ||
89 | |||
90 | // test never_type | ||
91 | // type Never = !; | ||
92 | fn never_type(p: &mut Parser) { | ||
93 | assert!(p.at(T![!])); | ||
94 | let m = p.start(); | ||
95 | p.bump(T![!]); | ||
96 | m.complete(p, NEVER_TYPE); | ||
97 | } | ||
98 | |||
99 | fn pointer_type(p: &mut Parser) { | ||
100 | assert!(p.at(T![*])); | ||
101 | let m = p.start(); | ||
102 | p.bump(T![*]); | ||
103 | |||
104 | match p.current() { | ||
105 | // test pointer_type_mut | ||
106 | // type M = *mut (); | ||
107 | // type C = *mut (); | ||
108 | T![mut] | T![const] => p.bump_any(), | ||
109 | _ => { | ||
110 | // test_err pointer_type_no_mutability | ||
111 | // type T = *(); | ||
112 | p.error( | ||
113 | "expected mut or const in raw pointer type \ | ||
114 | (use `*mut T` or `*const T` as appropriate)", | ||
115 | ); | ||
116 | } | ||
117 | }; | ||
118 | |||
119 | type_no_bounds(p); | ||
120 | m.complete(p, PTR_TYPE); | ||
121 | } | ||
122 | |||
123 | fn array_or_slice_type(p: &mut Parser) { | ||
124 | assert!(p.at(T!['['])); | ||
125 | let m = p.start(); | ||
126 | p.bump(T!['[']); | ||
127 | |||
128 | type_(p); | ||
129 | let kind = match p.current() { | ||
130 | // test slice_type | ||
131 | // type T = [()]; | ||
132 | T![']'] => { | ||
133 | p.bump(T![']']); | ||
134 | SLICE_TYPE | ||
135 | } | ||
136 | |||
137 | // test array_type | ||
138 | // type T = [(); 92]; | ||
139 | T![;] => { | ||
140 | p.bump(T![;]); | ||
141 | expressions::expr(p); | ||
142 | p.expect(T![']']); | ||
143 | ARRAY_TYPE | ||
144 | } | ||
145 | // test_err array_type_missing_semi | ||
146 | // type T = [() 92]; | ||
147 | _ => { | ||
148 | p.error("expected `;` or `]`"); | ||
149 | SLICE_TYPE | ||
150 | } | ||
151 | }; | ||
152 | m.complete(p, kind); | ||
153 | } | ||
154 | |||
155 | // test reference_type; | ||
156 | // type A = &(); | ||
157 | // type B = &'static (); | ||
158 | // type C = &mut (); | ||
159 | fn reference_type(p: &mut Parser) { | ||
160 | assert!(p.at(T![&])); | ||
161 | let m = p.start(); | ||
162 | p.bump(T![&]); | ||
163 | p.eat(LIFETIME); | ||
164 | p.eat(T![mut]); | ||
165 | type_no_bounds(p); | ||
166 | m.complete(p, REF_TYPE); | ||
167 | } | ||
168 | |||
169 | // test placeholder_type | ||
170 | // type Placeholder = _; | ||
171 | fn placeholder_type(p: &mut Parser) { | ||
172 | assert!(p.at(T![_])); | ||
173 | let m = p.start(); | ||
174 | p.bump(T![_]); | ||
175 | m.complete(p, INFER_TYPE); | ||
176 | } | ||
177 | |||
178 | // test fn_pointer_type | ||
179 | // type A = fn(); | ||
180 | // type B = unsafe fn(); | ||
181 | // type C = unsafe extern "C" fn(); | ||
182 | // type D = extern "C" fn ( u8 , ... ) -> u8; | ||
183 | fn fn_pointer_type(p: &mut Parser) { | ||
184 | let m = p.start(); | ||
185 | p.eat(T![unsafe]); | ||
186 | if p.at(T![extern]) { | ||
187 | abi(p); | ||
188 | } | ||
189 | // test_err fn_pointer_type_missing_fn | ||
190 | // type F = unsafe (); | ||
191 | if !p.eat(T![fn]) { | ||
192 | m.abandon(p); | ||
193 | p.error("expected `fn`"); | ||
194 | return; | ||
195 | } | ||
196 | if p.at(T!['(']) { | ||
197 | params::param_list_fn_ptr(p); | ||
198 | } else { | ||
199 | p.error("expected parameters") | ||
200 | } | ||
201 | // test fn_pointer_type_with_ret | ||
202 | // type F = fn() -> (); | ||
203 | opt_fn_ret_type(p); | ||
204 | m.complete(p, FN_PTR_TYPE); | ||
205 | } | ||
206 | |||
207 | pub(super) fn for_binder(p: &mut Parser) { | ||
208 | assert!(p.at(T![for])); | ||
209 | p.bump(T![for]); | ||
210 | if p.at(T![<]) { | ||
211 | type_params::opt_type_param_list(p); | ||
212 | } else { | ||
213 | p.error("expected `<`"); | ||
214 | } | ||
215 | } | ||
216 | |||
217 | // test for_type | ||
218 | // type A = for<'a> fn() -> (); | ||
219 | // type B = for<'a> unsafe extern "C" fn(&'a ()) -> (); | ||
220 | // type Obj = for<'a> PartialEq<&'a i32>; | ||
221 | pub(super) fn for_type(p: &mut Parser) { | ||
222 | assert!(p.at(T![for])); | ||
223 | let m = p.start(); | ||
224 | for_binder(p); | ||
225 | match p.current() { | ||
226 | T![fn] | T![unsafe] | T![extern] => {} | ||
227 | // OK: legacy trait object format | ||
228 | _ if paths::is_use_path_start(p) => {} | ||
229 | _ => { | ||
230 | p.error("expected a function pointer or path"); | ||
231 | } | ||
232 | } | ||
233 | type_no_bounds(p); | ||
234 | m.complete(p, FOR_TYPE); | ||
235 | } | ||
236 | |||
237 | // test impl_trait_type | ||
238 | // type A = impl Iterator<Item=Foo<'a>> + 'a; | ||
239 | fn impl_trait_type(p: &mut Parser) { | ||
240 | assert!(p.at(T![impl])); | ||
241 | let m = p.start(); | ||
242 | p.bump(T![impl]); | ||
243 | type_params::bounds_without_colon(p); | ||
244 | m.complete(p, IMPL_TRAIT_TYPE); | ||
245 | } | ||
246 | |||
247 | // test dyn_trait_type | ||
248 | // type A = dyn Iterator<Item=Foo<'a>> + 'a; | ||
249 | fn dyn_trait_type(p: &mut Parser) { | ||
250 | assert!(p.at(T![dyn])); | ||
251 | let m = p.start(); | ||
252 | p.bump(T![dyn]); | ||
253 | type_params::bounds_without_colon(p); | ||
254 | m.complete(p, DYN_TRAIT_TYPE); | ||
255 | } | ||
256 | |||
257 | // test path_type | ||
258 | // type A = Foo; | ||
259 | // type B = ::Foo; | ||
260 | // type C = self::Foo; | ||
261 | // type D = super::Foo; | ||
262 | pub(super) fn path_type(p: &mut Parser) { | ||
263 | path_type_(p, true) | ||
264 | } | ||
265 | |||
266 | // test macro_call_type | ||
267 | // type A = foo!(); | ||
268 | // type B = crate::foo!(); | ||
269 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | ||
270 | assert!(paths::is_path_start(p)); | ||
271 | let m = p.start(); | ||
272 | paths::type_path(p); | ||
273 | |||
274 | let kind = if p.at(T![!]) && !p.at(T![!=]) { | ||
275 | items::macro_call_after_excl(p); | ||
276 | MACRO_CALL | ||
277 | } else { | ||
278 | PATH_TYPE | ||
279 | }; | ||
280 | |||
281 | let path = m.complete(p, kind); | ||
282 | |||
283 | if allow_bounds { | ||
284 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | ||
289 | assert!(paths::is_path_start(p)); | ||
290 | let m = p.start(); | ||
291 | paths::type_path(p); | ||
292 | |||
293 | // test path_type_with_bounds | ||
294 | // fn foo() -> Box<T + 'f> {} | ||
295 | // fn foo() -> Box<dyn T + 'f> {} | ||
296 | let path = m.complete(p, PATH_TYPE); | ||
297 | if allow_bounds { | ||
298 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | /// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE | ||
303 | /// with a TYPE_BOUND_LIST | ||
304 | fn opt_path_type_bounds_as_dyn_trait_type(p: &mut Parser, path_type_marker: CompletedMarker) { | ||
305 | if !p.at(T![+]) { | ||
306 | return; | ||
307 | } | ||
308 | |||
309 | // First create a TYPE_BOUND from the completed PATH_TYPE | ||
310 | let m = path_type_marker.precede(p).complete(p, TYPE_BOUND); | ||
311 | |||
312 | // Next setup a marker for the TYPE_BOUND_LIST | ||
313 | let m = m.precede(p); | ||
314 | |||
315 | // This gets consumed here so it gets properly set | ||
316 | // in the TYPE_BOUND_LIST | ||
317 | p.eat(T![+]); | ||
318 | |||
319 | // Parse rest of the bounds into the TYPE_BOUND_LIST | ||
320 | let m = type_params::bounds_without_colon_m(p, m); | ||
321 | |||
322 | // Finally precede everything with DYN_TRAIT_TYPE | ||
323 | m.precede(p).complete(p, DYN_TRAIT_TYPE); | ||
324 | } | ||