3 pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
19 const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
23 // test_err struct_field_recover
24 // struct S { f pub g: () }
28 pub(crate) fn type_(p: &mut Parser) {
29 type_with_bounds_cond(p, true);
32 pub(super) fn type_no_bounds(p: &mut Parser) {
33 type_with_bounds_cond(p, false);
36 fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
38 T!['('] => paren_or_tuple_type(p),
39 T![!] => never_type(p),
41 T!['['] => array_or_slice_type(p),
43 T![_] => infer_type(p),
44 T![fn] | T![unsafe] | T![extern] => fn_ptr_type(p),
45 T![for] => for_type(p, allow_bounds),
46 T![impl] => impl_trait_type(p),
47 T![dyn] => dyn_trait_type(p),
48 // Some path types are not allowed to have bounds (no plus)
49 T![<] => path_type_(p, allow_bounds),
50 _ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds),
52 p.err_recover("expected type", TYPE_RECOVERY_SET);
57 pub(super) fn ascription(p: &mut Parser) {
62 fn paren_or_tuple_type(p: &mut Parser) {
63 assert!(p.at(T!['(']));
66 let mut n_types: u32 = 0;
67 let mut trailing_comma: bool = false;
68 while !p.at(EOF) && !p.at(T![')']) {
72 trailing_comma = true;
74 trailing_comma = false;
80 let kind = if n_types == 1 && !trailing_comma {
88 // test singleton_tuple_type
97 fn never_type(p: &mut Parser) {
101 m.complete(p, NEVER_TYPE);
104 fn ptr_type(p: &mut Parser) {
105 assert!(p.at(T![*]));
110 // test pointer_type_mut
113 T![mut] | T![const] => p.bump_any(),
115 // test_err pointer_type_no_mutability
118 "expected mut or const in raw pointer type \
119 (use `*mut T` or `*const T` as appropriate)",
125 m.complete(p, PTR_TYPE);
128 fn array_or_slice_type(p: &mut Parser) {
129 assert!(p.at(T!['[']));
134 let kind = match p.current() {
143 // type T = [(); 92];
146 expressions::expr(p);
150 // test_err array_type_missing_semi
153 p.error("expected `;` or `]`");
160 // test reference_type;
162 // type B = &'static ();
164 fn ref_type(p: &mut Parser) {
165 assert!(p.at(T![&]));
168 if p.at(LIFETIME_IDENT) {
173 m.complete(p, REF_TYPE);
176 // test placeholder_type
177 // type Placeholder = _;
178 fn infer_type(p: &mut Parser) {
179 assert!(p.at(T![_]));
182 m.complete(p, INFER_TYPE);
185 // test fn_pointer_type
187 // type B = unsafe fn();
188 // type C = unsafe extern "C" fn();
189 // type D = extern "C" fn ( u8 , ... ) -> u8;
190 fn fn_ptr_type(p: &mut Parser) {
193 if p.at(T![extern]) {
196 // test_err fn_pointer_type_missing_fn
197 // type F = unsafe ();
200 p.error("expected `fn`");
204 params::param_list_fn_ptr(p);
206 p.error("expected parameters")
208 // test fn_pointer_type_with_ret
209 // type F = fn() -> ();
211 m.complete(p, FN_PTR_TYPE);
214 pub(super) fn for_binder(p: &mut Parser) {
215 assert!(p.at(T![for]));
218 type_params::opt_generic_param_list(p);
220 p.error("expected `<`");
225 // type A = for<'a> fn() -> ();
226 // type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
227 // type Obj = for<'a> PartialEq<&'a i32>;
228 pub(super) fn for_type(p: &mut Parser, allow_bounds: bool) {
229 assert!(p.at(T![for]));
233 T![fn] | T![unsafe] | T![extern] => {}
234 // OK: legacy trait object format
235 _ if paths::is_use_path_start(p) => {}
237 p.error("expected a function pointer or path");
241 let completed = m.complete(p, FOR_TYPE);
243 // test no_dyn_trait_leading_for
244 // type A = for<'a> Test<'a> + Send;
246 opt_type_bounds_as_dyn_trait_type(p, completed);
250 // test impl_trait_type
251 // type A = impl Iterator<Item=Foo<'a>> + 'a;
252 fn impl_trait_type(p: &mut Parser) {
253 assert!(p.at(T![impl]));
256 type_params::bounds_without_colon(p);
257 m.complete(p, IMPL_TRAIT_TYPE);
260 // test dyn_trait_type
261 // type A = dyn Iterator<Item=Foo<'a>> + 'a;
262 fn dyn_trait_type(p: &mut Parser) {
263 assert!(p.at(T![dyn]));
266 type_params::bounds_without_colon(p);
267 m.complete(p, DYN_TRAIT_TYPE);
273 // type C = self::Foo;
274 // type D = super::Foo;
275 pub(super) fn path_type(p: &mut Parser) {
279 // test macro_call_type
281 // type B = crate::foo!();
282 fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
283 assert!(paths::is_path_start(p));
289 let kind = if p.at(T![!]) && !p.at(T![!=]) {
290 items::macro_call_after_excl(p);
291 m.complete(p, MACRO_CALL);
298 let path = r.complete(p, kind);
301 opt_type_bounds_as_dyn_trait_type(p, path);
305 pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
306 assert!(paths::is_path_start(p));
310 // test path_type_with_bounds
311 // fn foo() -> Box<T + 'f> {}
312 // fn foo() -> Box<dyn T + 'f> {}
313 let path = m.complete(p, PATH_TYPE);
315 opt_type_bounds_as_dyn_trait_type(p, path);
319 /// This turns a parsed PATH_TYPE or FOR_TYPE optionally into a DYN_TRAIT_TYPE
320 /// with a TYPE_BOUND_LIST
321 fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) {
324 SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
330 // First create a TYPE_BOUND from the completed PATH_TYPE
331 let m = type_marker.precede(p).complete(p, TYPE_BOUND);
333 // Next setup a marker for the TYPE_BOUND_LIST
334 let m = m.precede(p);
336 // This gets consumed here so it gets properly set
337 // in the TYPE_BOUND_LIST
340 // Parse rest of the bounds into the TYPE_BOUND_LIST
341 let m = type_params::bounds_without_colon_m(p, m);
343 // Finally precede everything with DYN_TRAIT_TYPE
344 m.precede(p).complete(p, DYN_TRAIT_TYPE);