1 //! FIXME: write short doc here
5 pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
21 const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
25 // test_err struct_field_recover
26 // struct S { f pub g: () }
30 pub(crate) fn type_(p: &mut Parser) {
31 type_with_bounds_cond(p, true);
34 pub(super) fn type_no_bounds(p: &mut Parser) {
35 type_with_bounds_cond(p, false);
38 fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
40 T!['('] => paren_or_tuple_type(p),
41 T![!] => never_type(p),
43 T!['['] => array_or_slice_type(p),
45 T![_] => infer_type(p),
46 T![fn] | T![unsafe] | T![extern] => fn_ptr_type(p),
47 T![for] => for_type(p, allow_bounds),
48 T![impl] => impl_trait_type(p),
49 T![dyn] => dyn_trait_type(p),
50 // Some path types are not allowed to have bounds (no plus)
51 T![<] => path_type_(p, allow_bounds),
52 _ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds),
54 p.err_recover("expected type", TYPE_RECOVERY_SET);
59 pub(super) fn ascription(p: &mut Parser) {
64 fn paren_or_tuple_type(p: &mut Parser) {
65 assert!(p.at(T!['(']));
68 let mut n_types: u32 = 0;
69 let mut trailing_comma: bool = false;
70 while !p.at(EOF) && !p.at(T![')']) {
74 trailing_comma = true;
76 trailing_comma = false;
82 let kind = if n_types == 1 && !trailing_comma {
90 // test singleton_tuple_type
99 fn never_type(p: &mut Parser) {
100 assert!(p.at(T![!]));
103 m.complete(p, NEVER_TYPE);
106 fn ptr_type(p: &mut Parser) {
107 assert!(p.at(T![*]));
112 // test pointer_type_mut
115 T![mut] | T![const] => p.bump_any(),
117 // test_err pointer_type_no_mutability
120 "expected mut or const in raw pointer type \
121 (use `*mut T` or `*const T` as appropriate)",
127 m.complete(p, PTR_TYPE);
130 fn array_or_slice_type(p: &mut Parser) {
131 assert!(p.at(T!['[']));
136 let kind = match p.current() {
145 // type T = [(); 92];
148 expressions::expr(p);
152 // test_err array_type_missing_semi
155 p.error("expected `;` or `]`");
162 // test reference_type;
164 // type B = &'static ();
166 fn ref_type(p: &mut Parser) {
167 assert!(p.at(T![&]));
170 if p.at(LIFETIME_IDENT) {
175 m.complete(p, REF_TYPE);
178 // test placeholder_type
179 // type Placeholder = _;
180 fn infer_type(p: &mut Parser) {
181 assert!(p.at(T![_]));
184 m.complete(p, INFER_TYPE);
187 // test fn_pointer_type
189 // type B = unsafe fn();
190 // type C = unsafe extern "C" fn();
191 // type D = extern "C" fn ( u8 , ... ) -> u8;
192 fn fn_ptr_type(p: &mut Parser) {
195 if p.at(T![extern]) {
198 // test_err fn_pointer_type_missing_fn
199 // type F = unsafe ();
202 p.error("expected `fn`");
206 params::param_list_fn_ptr(p);
208 p.error("expected parameters")
210 // test fn_pointer_type_with_ret
211 // type F = fn() -> ();
213 m.complete(p, FN_PTR_TYPE);
216 pub(super) fn for_binder(p: &mut Parser) {
217 assert!(p.at(T![for]));
220 type_params::opt_generic_param_list(p);
222 p.error("expected `<`");
227 // type A = for<'a> fn() -> ();
228 // type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
229 // type Obj = for<'a> PartialEq<&'a i32>;
230 pub(super) fn for_type(p: &mut Parser, allow_bounds: bool) {
231 assert!(p.at(T![for]));
235 T![fn] | T![unsafe] | T![extern] => {}
236 // OK: legacy trait object format
237 _ if paths::is_use_path_start(p) => {}
239 p.error("expected a function pointer or path");
243 let completed = m.complete(p, FOR_TYPE);
245 // test no_dyn_trait_leading_for
246 // type A = for<'a> Test<'a> + Send;
248 opt_type_bounds_as_dyn_trait_type(p, completed);
252 // test impl_trait_type
253 // type A = impl Iterator<Item=Foo<'a>> + 'a;
254 fn impl_trait_type(p: &mut Parser) {
255 assert!(p.at(T![impl]));
258 type_params::bounds_without_colon(p);
259 m.complete(p, IMPL_TRAIT_TYPE);
262 // test dyn_trait_type
263 // type A = dyn Iterator<Item=Foo<'a>> + 'a;
264 fn dyn_trait_type(p: &mut Parser) {
265 assert!(p.at(T![dyn]));
268 type_params::bounds_without_colon(p);
269 m.complete(p, DYN_TRAIT_TYPE);
275 // type C = self::Foo;
276 // type D = super::Foo;
277 pub(super) fn path_type(p: &mut Parser) {
281 // test macro_call_type
283 // type B = crate::foo!();
284 fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
285 assert!(paths::is_path_start(p));
291 let kind = if p.at(T![!]) && !p.at(T![!=]) {
292 items::macro_call_after_excl(p);
293 m.complete(p, MACRO_CALL);
300 let path = r.complete(p, kind);
303 opt_type_bounds_as_dyn_trait_type(p, path);
307 pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
308 assert!(paths::is_path_start(p));
312 // test path_type_with_bounds
313 // fn foo() -> Box<T + 'f> {}
314 // fn foo() -> Box<dyn T + 'f> {}
315 let path = m.complete(p, PATH_TYPE);
317 opt_type_bounds_as_dyn_trait_type(p, path);
321 /// This turns a parsed PATH_TYPE or FOR_TYPE optionally into a DYN_TRAIT_TYPE
322 /// with a TYPE_BOUND_LIST
323 fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) {
326 SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
332 // First create a TYPE_BOUND from the completed PATH_TYPE
333 let m = type_marker.precede(p).complete(p, TYPE_BOUND);
335 // Next setup a marker for the TYPE_BOUND_LIST
336 let m = m.precede(p);
338 // This gets consumed here so it gets properly set
339 // in the TYPE_BOUND_LIST
342 // Parse rest of the bounds into the TYPE_BOUND_LIST
343 let m = type_params::bounds_without_colon_m(p, m);
345 // Finally precede everything with DYN_TRAIT_TYPE
346 m.precede(p).complete(p, DYN_TRAIT_TYPE);