• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::{Parser, PathStyle, TokenType};
2 
3 use crate::errors::{
4     self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
5     FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
6     InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
7     ReturnTypesUseThinArrow,
8 };
9 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
10 
11 use ast::DUMMY_NODE_ID;
12 use rustc_ast::ptr::P;
13 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
14 use rustc_ast::util::case::Case;
15 use rustc_ast::{
16     self as ast, BareFnTy, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam,
17     Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier,
18     TraitObjectSyntax, Ty, TyKind,
19 };
20 use rustc_errors::{Applicability, PResult};
21 use rustc_span::source_map::Span;
22 use rustc_span::symbol::{kw, sym, Ident};
23 use rustc_span::Symbol;
24 use thin_vec::{thin_vec, ThinVec};
25 
26 /// Any `?`, `!`, or `~const` modifiers that appear at the start of a bound.
27 struct BoundModifiers {
28     /// `?Trait`.
29     bound_polarity: BoundPolarity,
30 
31     /// `~const Trait`.
32     maybe_const: Option<Span>,
33 }
34 
35 impl BoundModifiers {
to_trait_bound_modifier(&self) -> TraitBoundModifier36     fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
37         match (self.bound_polarity, self.maybe_const) {
38             (BoundPolarity::Positive, None) => TraitBoundModifier::None,
39             (BoundPolarity::Negative(_), None) => TraitBoundModifier::Negative,
40             (BoundPolarity::Maybe(_), None) => TraitBoundModifier::Maybe,
41             (BoundPolarity::Positive, Some(_)) => TraitBoundModifier::MaybeConst,
42             (BoundPolarity::Negative(_), Some(_)) => TraitBoundModifier::MaybeConstNegative,
43             (BoundPolarity::Maybe(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
44         }
45     }
46 }
47 
48 #[derive(Copy, Clone, PartialEq)]
49 pub(super) enum AllowPlus {
50     Yes,
51     No,
52 }
53 
54 #[derive(PartialEq)]
55 pub(super) enum RecoverQPath {
56     Yes,
57     No,
58 }
59 
60 pub(super) enum RecoverQuestionMark {
61     Yes,
62     No,
63 }
64 
65 /// Signals whether parsing a type should recover `->`.
66 ///
67 /// More specifically, when parsing a function like:
68 /// ```compile_fail
69 /// fn foo() => u8 { 0 }
70 /// fn bar(): u8 { 0 }
71 /// ```
72 /// The compiler will try to recover interpreting `foo() => u8` as `foo() -> u8` when calling
73 /// `parse_ty` with anything except `RecoverReturnSign::No`, and it will try to recover `bar(): u8`
74 /// as `bar() -> u8` when passing `RecoverReturnSign::Yes` to `parse_ty`
75 #[derive(Copy, Clone, PartialEq)]
76 pub(super) enum RecoverReturnSign {
77     Yes,
78     OnlyFatArrow,
79     No,
80 }
81 
82 impl RecoverReturnSign {
83     /// [RecoverReturnSign::Yes] allows for recovering `fn foo() => u8` and `fn foo(): u8`,
84     /// [RecoverReturnSign::OnlyFatArrow] allows for recovering only `fn foo() => u8` (recovering
85     /// colons can cause problems when parsing where clauses), and
86     /// [RecoverReturnSign::No] doesn't allow for any recovery of the return type arrow
can_recover(self, token: &TokenKind) -> bool87     fn can_recover(self, token: &TokenKind) -> bool {
88         match self {
89             Self::Yes => matches!(token, token::FatArrow | token::Colon),
90             Self::OnlyFatArrow => matches!(token, token::FatArrow),
91             Self::No => false,
92         }
93     }
94 }
95 
96 // Is `...` (`CVarArgs`) legal at this level of type parsing?
97 #[derive(PartialEq)]
98 enum AllowCVariadic {
99     Yes,
100     No,
101 }
102 
103 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
104 /// `IDENT<<u8 as Trait>::AssocTy>`.
105 ///
106 /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
107 /// that `IDENT` is not the ident of a fn trait.
can_continue_type_after_non_fn_ident(t: &Token) -> bool108 fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
109     t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl)
110 }
111 
112 impl<'a> Parser<'a> {
113     /// Parses a type.
parse_ty(&mut self) -> PResult<'a, P<Ty>>114     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
115         self.parse_ty_common(
116             AllowPlus::Yes,
117             AllowCVariadic::No,
118             RecoverQPath::Yes,
119             RecoverReturnSign::Yes,
120             None,
121             RecoverQuestionMark::Yes,
122         )
123     }
124 
parse_ty_with_generics_recovery( &mut self, ty_params: &Generics, ) -> PResult<'a, P<Ty>>125     pub(super) fn parse_ty_with_generics_recovery(
126         &mut self,
127         ty_params: &Generics,
128     ) -> PResult<'a, P<Ty>> {
129         self.parse_ty_common(
130             AllowPlus::Yes,
131             AllowCVariadic::No,
132             RecoverQPath::Yes,
133             RecoverReturnSign::Yes,
134             Some(ty_params),
135             RecoverQuestionMark::Yes,
136         )
137     }
138 
139     /// Parse a type suitable for a function or function pointer parameter.
140     /// The difference from `parse_ty` is that this version allows `...`
141     /// (`CVarArgs`) at the top level of the type.
parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>>142     pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
143         self.parse_ty_common(
144             AllowPlus::Yes,
145             AllowCVariadic::Yes,
146             RecoverQPath::Yes,
147             RecoverReturnSign::Yes,
148             None,
149             RecoverQuestionMark::Yes,
150         )
151     }
152 
153     /// Parses a type in restricted contexts where `+` is not permitted.
154     ///
155     /// Example 1: `&'a TYPE`
156     ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
157     /// Example 2: `value1 as TYPE + value2`
158     ///     `+` is prohibited to avoid interactions with expression grammar.
parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>>159     pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
160         self.parse_ty_common(
161             AllowPlus::No,
162             AllowCVariadic::No,
163             RecoverQPath::Yes,
164             RecoverReturnSign::Yes,
165             None,
166             RecoverQuestionMark::Yes,
167         )
168     }
169 
170     /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
171     /// for better diagnostics involving `?`.
parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>>172     pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
173         self.parse_ty_common(
174             AllowPlus::No,
175             AllowCVariadic::No,
176             RecoverQPath::Yes,
177             RecoverReturnSign::Yes,
178             None,
179             RecoverQuestionMark::No,
180         )
181     }
182 
parse_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>>183     pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
184         self.parse_ty_common(
185             AllowPlus::Yes,
186             AllowCVariadic::No,
187             RecoverQPath::Yes,
188             RecoverReturnSign::Yes,
189             None,
190             RecoverQuestionMark::No,
191         )
192     }
193 
194     /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>>195     pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
196         self.parse_ty_common(
197             AllowPlus::Yes,
198             AllowCVariadic::Yes,
199             RecoverQPath::Yes,
200             RecoverReturnSign::OnlyFatArrow,
201             None,
202             RecoverQuestionMark::Yes,
203         )
204     }
205 
206     /// Parses an optional return type `[ -> TY ]` in a function declaration.
parse_ret_ty( &mut self, allow_plus: AllowPlus, recover_qpath: RecoverQPath, recover_return_sign: RecoverReturnSign, ) -> PResult<'a, FnRetTy>207     pub(super) fn parse_ret_ty(
208         &mut self,
209         allow_plus: AllowPlus,
210         recover_qpath: RecoverQPath,
211         recover_return_sign: RecoverReturnSign,
212     ) -> PResult<'a, FnRetTy> {
213         Ok(if self.eat(&token::RArrow) {
214             // FIXME(Centril): Can we unconditionally `allow_plus`?
215             let ty = self.parse_ty_common(
216                 allow_plus,
217                 AllowCVariadic::No,
218                 recover_qpath,
219                 recover_return_sign,
220                 None,
221                 RecoverQuestionMark::Yes,
222             )?;
223             FnRetTy::Ty(ty)
224         } else if recover_return_sign.can_recover(&self.token.kind) {
225             // Don't `eat` to prevent `=>` from being added as an expected token which isn't
226             // actually expected and could only confuse users
227             self.bump();
228             self.sess.emit_err(ReturnTypesUseThinArrow { span: self.prev_token.span });
229             let ty = self.parse_ty_common(
230                 allow_plus,
231                 AllowCVariadic::No,
232                 recover_qpath,
233                 recover_return_sign,
234                 None,
235                 RecoverQuestionMark::Yes,
236             )?;
237             FnRetTy::Ty(ty)
238         } else {
239             FnRetTy::Default(self.token.span.shrink_to_lo())
240         })
241     }
242 
parse_ty_common( &mut self, allow_plus: AllowPlus, allow_c_variadic: AllowCVariadic, recover_qpath: RecoverQPath, recover_return_sign: RecoverReturnSign, ty_generics: Option<&Generics>, recover_question_mark: RecoverQuestionMark, ) -> PResult<'a, P<Ty>>243     fn parse_ty_common(
244         &mut self,
245         allow_plus: AllowPlus,
246         allow_c_variadic: AllowCVariadic,
247         recover_qpath: RecoverQPath,
248         recover_return_sign: RecoverReturnSign,
249         ty_generics: Option<&Generics>,
250         recover_question_mark: RecoverQuestionMark,
251     ) -> PResult<'a, P<Ty>> {
252         let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
253         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
254         maybe_whole!(self, NtTy, |x| x);
255 
256         let lo = self.token.span;
257         let mut impl_dyn_multi = false;
258         let kind = if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
259             self.parse_ty_tuple_or_parens(lo, allow_plus)?
260         } else if self.eat(&token::Not) {
261             // Never type `!`
262             TyKind::Never
263         } else if self.eat(&token::BinOp(token::Star)) {
264             self.parse_ty_ptr()?
265         } else if self.eat(&token::OpenDelim(Delimiter::Bracket)) {
266             self.parse_array_or_slice_ty()?
267         } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
268             // Reference
269             self.expect_and()?;
270             self.parse_borrowed_pointee()?
271         } else if self.eat_keyword_noexpect(kw::Typeof) {
272             self.parse_typeof_ty()?
273         } else if self.eat_keyword(kw::Underscore) {
274             // A type to be inferred `_`
275             TyKind::Infer
276         } else if self.check_fn_front_matter(false, Case::Sensitive) {
277             // Function pointer type
278             self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)?
279         } else if self.check_keyword(kw::For) {
280             // Function pointer type or bound list (trait object type) starting with a poly-trait.
281             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
282             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
283             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
284             if self.check_fn_front_matter(false, Case::Sensitive) {
285                 self.parse_ty_bare_fn(
286                     lo,
287                     lifetime_defs,
288                     Some(self.prev_token.span.shrink_to_lo()),
289                     recover_return_sign,
290                 )?
291             } else {
292                 let path = self.parse_path(PathStyle::Type)?;
293                 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
294                 self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
295             }
296         } else if self.eat_keyword(kw::Impl) {
297             self.parse_impl_ty(&mut impl_dyn_multi)?
298         } else if self.is_explicit_dyn_type() {
299             self.parse_dyn_ty(&mut impl_dyn_multi)?
300         } else if self.eat_lt() {
301             // Qualified path
302             let (qself, path) = self.parse_qpath(PathStyle::Type)?;
303             TyKind::Path(Some(qself), path)
304         } else if self.check_path() {
305             self.parse_path_start_ty(lo, allow_plus, ty_generics)?
306         } else if self.can_begin_bound() {
307             self.parse_bare_trait_object(lo, allow_plus)?
308         } else if self.eat(&token::DotDotDot) {
309             match allow_c_variadic {
310                 AllowCVariadic::Yes => TyKind::CVarArgs,
311                 AllowCVariadic::No => {
312                     // FIXME(Centril): Should we just allow `...` syntactically
313                     // anywhere in a type and use semantic restrictions instead?
314                     self.sess.emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) });
315                     TyKind::Err
316                 }
317             }
318         } else {
319             let msg = format!("expected type, found {}", super::token_descr(&self.token));
320             let mut err = self.struct_span_err(self.token.span, msg);
321             err.span_label(self.token.span, "expected type");
322             return Err(err);
323         };
324 
325         let span = lo.to(self.prev_token.span);
326         let mut ty = self.mk_ty(span, kind);
327 
328         // Try to recover from use of `+` with incorrect priority.
329         match allow_plus {
330             AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
331             AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
332         }
333         if let RecoverQuestionMark::Yes = recover_question_mark {
334             ty = self.maybe_recover_from_question_mark(ty);
335         }
336         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
337     }
338 
339     /// Parses either:
340     /// - `(TYPE)`, a parenthesized type.
341     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind>342     fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
343         let mut trailing_plus = false;
344         let (ts, trailing) = self.parse_paren_comma_seq(|p| {
345             let ty = p.parse_ty()?;
346             trailing_plus = p.prev_token.kind == TokenKind::BinOp(token::Plus);
347             Ok(ty)
348         })?;
349 
350         if ts.len() == 1 && !trailing {
351             let ty = ts.into_iter().next().unwrap().into_inner();
352             let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
353             match ty.kind {
354                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
355                 TyKind::Path(None, path) if maybe_bounds => {
356                     self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
357                 }
358                 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
359                     if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
360                 {
361                     self.parse_remaining_bounds(bounds, true)
362                 }
363                 // `(TYPE)`
364                 _ => Ok(TyKind::Paren(P(ty))),
365             }
366         } else {
367             Ok(TyKind::Tup(ts))
368         }
369     }
370 
parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind>371     fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
372         let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
373         let bounds = self.parse_generic_bounds_common(allow_plus)?;
374         if lt_no_plus {
375             self.sess.emit_err(NeedPlusAfterTraitObjectLifetime { span: lo });
376         }
377         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
378     }
379 
parse_remaining_bounds_path( &mut self, generic_params: ThinVec<GenericParam>, path: ast::Path, lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind>380     fn parse_remaining_bounds_path(
381         &mut self,
382         generic_params: ThinVec<GenericParam>,
383         path: ast::Path,
384         lo: Span,
385         parse_plus: bool,
386     ) -> PResult<'a, TyKind> {
387         let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
388         let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
389         self.parse_remaining_bounds(bounds, parse_plus)
390     }
391 
392     /// Parse the remainder of a bare trait object type given an already parsed list.
parse_remaining_bounds( &mut self, mut bounds: GenericBounds, plus: bool, ) -> PResult<'a, TyKind>393     fn parse_remaining_bounds(
394         &mut self,
395         mut bounds: GenericBounds,
396         plus: bool,
397     ) -> PResult<'a, TyKind> {
398         if plus {
399             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
400             bounds.append(&mut self.parse_generic_bounds()?);
401         }
402         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
403     }
404 
405     /// Parses a raw pointer type: `*[const | mut] $type`.
parse_ty_ptr(&mut self) -> PResult<'a, TyKind>406     fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
407         let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
408             let span = self.prev_token.span;
409             self.sess.emit_err(ExpectedMutOrConstInRawPointerType {
410                 span,
411                 after_asterisk: span.shrink_to_hi(),
412             });
413             Mutability::Not
414         });
415         let ty = self.parse_ty_no_plus()?;
416         Ok(TyKind::Ptr(MutTy { ty, mutbl }))
417     }
418 
419     /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
420     /// The opening `[` bracket is already eaten.
parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind>421     fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
422         let elt_ty = match self.parse_ty() {
423             Ok(ty) => ty,
424             Err(mut err)
425                 if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket))
426                     | self.look_ahead(1, |t| t.kind == token::Semi) =>
427             {
428                 // Recover from `[LIT; EXPR]` and `[LIT]`
429                 self.bump();
430                 err.emit();
431                 self.mk_ty(self.prev_token.span, TyKind::Err)
432             }
433             Err(err) => return Err(err),
434         };
435 
436         let ty = if self.eat(&token::Semi) {
437             let mut length = self.parse_expr_anon_const()?;
438             if let Err(e) = self.expect(&token::CloseDelim(Delimiter::Bracket)) {
439                 // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
440                 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
441                 self.expect(&token::CloseDelim(Delimiter::Bracket))?;
442             }
443             TyKind::Array(elt_ty, length)
444         } else {
445             self.expect(&token::CloseDelim(Delimiter::Bracket))?;
446             TyKind::Slice(elt_ty)
447         };
448 
449         Ok(ty)
450     }
451 
parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind>452     fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
453         let and_span = self.prev_token.span;
454         let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
455         let mut mutbl = self.parse_mutability();
456         if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
457             // A lifetime is invalid here: it would be part of a bare trait bound, which requires
458             // it to be followed by a plus, but we disallow plus in the pointee type.
459             // So we can handle this case as an error here, and suggest `'a mut`.
460             // If there *is* a plus next though, handling the error later provides better suggestions
461             // (like adding parentheses)
462             if !self.look_ahead(1, |t| t.is_like_plus()) {
463                 let lifetime_span = self.token.span;
464                 let span = and_span.to(lifetime_span);
465 
466                 let (suggest_lifetime, snippet) =
467                     if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
468                         (Some(span), lifetime_src)
469                     } else {
470                         (None, String::new())
471                     };
472                 self.sess.emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
473 
474                 opt_lifetime = Some(self.expect_lifetime());
475             }
476         } else if self.token.is_keyword(kw::Dyn)
477             && mutbl == Mutability::Not
478             && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
479         {
480             // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
481             let span = and_span.to(self.look_ahead(1, |t| t.span));
482             self.sess.emit_err(DynAfterMut { span });
483 
484             // Recovery
485             mutbl = Mutability::Mut;
486             let (dyn_tok, dyn_tok_sp) = (self.token.clone(), self.token_spacing);
487             self.bump();
488             self.bump_with((dyn_tok, dyn_tok_sp));
489         }
490         let ty = self.parse_ty_no_plus()?;
491         Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }))
492     }
493 
494     // Parses the `typeof(EXPR)`.
495     // To avoid ambiguity, the type is surrounded by parentheses.
parse_typeof_ty(&mut self) -> PResult<'a, TyKind>496     fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
497         self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
498         let expr = self.parse_expr_anon_const()?;
499         self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
500         Ok(TyKind::Typeof(expr))
501     }
502 
503     /// Parses a function pointer type (`TyKind::BareFn`).
504     /// ```ignore (illustrative)
505     ///    [unsafe] [extern "ABI"] fn (S) -> T
506     /// //  ^~~~~^          ^~~~^     ^~^    ^
507     /// //    |               |        |     |
508     /// //    |               |        |   Return type
509     /// // Function Style    ABI  Parameter types
510     /// ```
511     /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
parse_ty_bare_fn( &mut self, lo: Span, mut params: ThinVec<GenericParam>, param_insertion_point: Option<Span>, recover_return_sign: RecoverReturnSign, ) -> PResult<'a, TyKind>512     fn parse_ty_bare_fn(
513         &mut self,
514         lo: Span,
515         mut params: ThinVec<GenericParam>,
516         param_insertion_point: Option<Span>,
517         recover_return_sign: RecoverReturnSign,
518     ) -> PResult<'a, TyKind> {
519         let inherited_vis = rustc_ast::Visibility {
520             span: rustc_span::DUMMY_SP,
521             kind: rustc_ast::VisibilityKind::Inherited,
522             tokens: None,
523         };
524         let span_start = self.token.span;
525         let ast::FnHeader { ext, unsafety, constness, asyncness } =
526             self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
527         if self.may_recover() && self.token.kind == TokenKind::Lt {
528             self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
529         }
530         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
531         let whole_span = lo.to(self.prev_token.span);
532         if let ast::Const::Yes(span) = constness {
533             // If we ever start to allow `const fn()`, then update
534             // feature gating for `#![feature(const_extern_fn)]` to
535             // cover it.
536             self.sess.emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
537         }
538         if let ast::Async::Yes { span, .. } = asyncness {
539             self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
540         }
541         let decl_span = span_start.to(self.token.span);
542         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
543     }
544 
545     /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
recover_fn_ptr_with_generics( &mut self, lo: Span, params: &mut ThinVec<GenericParam>, param_insertion_point: Option<Span>, ) -> PResult<'a, ()>546     fn recover_fn_ptr_with_generics(
547         &mut self,
548         lo: Span,
549         params: &mut ThinVec<GenericParam>,
550         param_insertion_point: Option<Span>,
551     ) -> PResult<'a, ()> {
552         let generics = self.parse_generics()?;
553         let arity = generics.params.len();
554 
555         let mut lifetimes: ThinVec<_> = generics
556             .params
557             .into_iter()
558             .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
559             .collect();
560 
561         let sugg = if !lifetimes.is_empty() {
562             let snippet =
563                 lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
564 
565             let (left, snippet) = if let Some(span) = param_insertion_point {
566                 (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
567             } else {
568                 (lo.shrink_to_lo(), format!("for<{snippet}> "))
569             };
570 
571             Some(FnPtrWithGenericsSugg {
572                 left,
573                 snippet,
574                 right: generics.span,
575                 arity,
576                 for_param_list_exists: param_insertion_point.is_some(),
577             })
578         } else {
579             None
580         };
581 
582         self.sess.emit_err(FnPtrWithGenerics { span: generics.span, sugg });
583         params.append(&mut lifetimes);
584         Ok(())
585     }
586 
587     /// Parses an `impl B0 + ... + Bn` type.
parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind>588     fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
589         // Always parse bounds greedily for better error recovery.
590         if self.token.is_lifetime() {
591             self.look_ahead(1, |t| {
592                 if let token::Ident(sym, _) = t.kind {
593                     // parse pattern with "'a Sized" we're supposed to give suggestion like
594                     // "'a + Sized"
595                     self.sess.emit_err(errors::MissingPlusBounds {
596                         span: self.token.span,
597                         hi: self.token.span.shrink_to_hi(),
598                         sym,
599                     });
600                 }
601             })
602         }
603         let bounds = self.parse_generic_bounds()?;
604         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
605         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
606     }
607 
608     /// Is a `dyn B0 + ... + Bn` type allowed here?
is_explicit_dyn_type(&mut self) -> bool609     fn is_explicit_dyn_type(&mut self) -> bool {
610         self.check_keyword(kw::Dyn)
611             && (self.token.uninterpolated_span().rust_2018()
612                 || self.look_ahead(1, |t| {
613                     (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star))
614                         && !can_continue_type_after_non_fn_ident(t)
615                 }))
616     }
617 
618     /// Parses a `dyn B0 + ... + Bn` type.
619     ///
620     /// Note that this does *not* parse bare trait objects.
parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind>621     fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
622         let lo = self.token.span;
623         self.bump(); // `dyn`
624 
625         // parse dyn* types
626         let syntax = if self.eat(&TokenKind::BinOp(token::Star)) {
627             self.sess.gated_spans.gate(sym::dyn_star, lo.to(self.prev_token.span));
628             TraitObjectSyntax::DynStar
629         } else {
630             TraitObjectSyntax::Dyn
631         };
632 
633         // Always parse bounds greedily for better error recovery.
634         let bounds = self.parse_generic_bounds()?;
635         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
636         Ok(TyKind::TraitObject(bounds, syntax))
637     }
638 
639     /// Parses a type starting with a path.
640     ///
641     /// This can be:
642     /// 1. a type macro, `mac!(...)`,
643     /// 2. a bare trait object, `B0 + ... + Bn`,
644     /// 3. or a path, `path::to::MyType`.
parse_path_start_ty( &mut self, lo: Span, allow_plus: AllowPlus, ty_generics: Option<&Generics>, ) -> PResult<'a, TyKind>645     fn parse_path_start_ty(
646         &mut self,
647         lo: Span,
648         allow_plus: AllowPlus,
649         ty_generics: Option<&Generics>,
650     ) -> PResult<'a, TyKind> {
651         // Simple path
652         let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
653         if self.eat(&token::Not) {
654             // Macro invocation in type position
655             Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
656         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
657             // `Trait1 + Trait2 + 'a`
658             self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
659         } else {
660             // Just a type path.
661             Ok(TyKind::Path(None, path))
662         }
663     }
664 
parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds>665     pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
666         self.parse_generic_bounds_common(AllowPlus::Yes)
667     }
668 
669     /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
670     ///
671     /// See `parse_generic_bound` for the `BOUND` grammar.
parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds>672     fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
673         let mut bounds = Vec::new();
674 
675         // In addition to looping while we find generic bounds:
676         // We continue even if we find a keyword. This is necessary for error recovery on,
677         // for example, `impl fn()`. The only keyword that can go after generic bounds is
678         // `where`, so stop if it's it.
679         // We also continue if we find types (not traits), again for error recovery.
680         while self.can_begin_bound()
681             || (self.may_recover()
682                 && (self.token.can_begin_type()
683                     || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
684         {
685             if self.token.is_keyword(kw::Dyn) {
686                 // Account for `&dyn Trait + dyn Other`.
687                 self.sess.emit_err(InvalidDynKeyword { span: self.token.span });
688                 self.bump();
689             }
690             bounds.push(self.parse_generic_bound()?);
691             if allow_plus == AllowPlus::No || !self.eat_plus() {
692                 break;
693             }
694         }
695 
696         Ok(bounds)
697     }
698 
699     /// Can the current token begin a bound?
can_begin_bound(&mut self) -> bool700     fn can_begin_bound(&mut self) -> bool {
701         // This needs to be synchronized with `TokenKind::can_begin_bound`.
702         self.check_path()
703             || self.check_lifetime()
704             || self.check(&token::Not)
705             || self.check(&token::Question)
706             || self.check(&token::Tilde)
707             || self.check_keyword(kw::For)
708             || self.check(&token::OpenDelim(Delimiter::Parenthesis))
709     }
710 
711     /// Parses a bound according to the grammar:
712     /// ```ebnf
713     /// BOUND = TY_BOUND | LT_BOUND
714     /// ```
parse_generic_bound(&mut self) -> PResult<'a, GenericBound>715     fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
716         let lo = self.token.span;
717         let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
718         let inner_lo = self.token.span;
719 
720         let modifiers = self.parse_ty_bound_modifiers()?;
721         let bound = if self.token.is_lifetime() {
722             self.error_lt_bound_with_modifiers(modifiers);
723             self.parse_generic_lt_bound(lo, inner_lo, has_parens)?
724         } else {
725             self.parse_generic_ty_bound(lo, has_parens, modifiers)?
726         };
727 
728         Ok(bound)
729     }
730 
731     /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
732     /// ```ebnf
733     /// LT_BOUND = LIFETIME
734     /// ```
parse_generic_lt_bound( &mut self, lo: Span, inner_lo: Span, has_parens: bool, ) -> PResult<'a, GenericBound>735     fn parse_generic_lt_bound(
736         &mut self,
737         lo: Span,
738         inner_lo: Span,
739         has_parens: bool,
740     ) -> PResult<'a, GenericBound> {
741         let bound = GenericBound::Outlives(self.expect_lifetime());
742         if has_parens {
743             // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
744             // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
745             self.recover_paren_lifetime(lo, inner_lo)?;
746         }
747         Ok(bound)
748     }
749 
750     /// Emits an error if any trait bound modifiers were present.
error_lt_bound_with_modifiers(&self, modifiers: BoundModifiers)751     fn error_lt_bound_with_modifiers(&self, modifiers: BoundModifiers) {
752         if let Some(span) = modifiers.maybe_const {
753             self.sess.emit_err(errors::TildeConstLifetime { span });
754         }
755 
756         match modifiers.bound_polarity {
757             BoundPolarity::Positive => {}
758             BoundPolarity::Negative(span) => {
759                 self.sess.emit_err(errors::ModifierLifetime { span, sigil: "!" });
760             }
761             BoundPolarity::Maybe(span) => {
762                 self.sess.emit_err(errors::ModifierLifetime { span, sigil: "?" });
763             }
764         }
765     }
766 
767     /// Recover on `('lifetime)` with `(` already eaten.
recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()>768     fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> {
769         let inner_span = inner_lo.to(self.prev_token.span);
770         self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
771         let span = lo.to(self.prev_token.span);
772         let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(inner_span) {
773             (Some(span), snippet)
774         } else {
775             (None, String::new())
776         };
777 
778         self.sess.emit_err(errors::ParenthesizedLifetime { span, sugg, snippet });
779         Ok(())
780     }
781 
782     /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `~const Trait`.
783     ///
784     /// If no modifiers are present, this does not consume any tokens.
785     ///
786     /// ```ebnf
787     /// TY_BOUND_MODIFIERS = ["~const"] ["?"]
788     /// ```
parse_ty_bound_modifiers(&mut self) -> PResult<'a, BoundModifiers>789     fn parse_ty_bound_modifiers(&mut self) -> PResult<'a, BoundModifiers> {
790         let maybe_const = if self.eat(&token::Tilde) {
791             let tilde = self.prev_token.span;
792             self.expect_keyword(kw::Const)?;
793             let span = tilde.to(self.prev_token.span);
794             self.sess.gated_spans.gate(sym::const_trait_impl, span);
795             Some(span)
796         } else if self.eat_keyword(kw::Const) {
797             let span = self.prev_token.span;
798             self.sess.gated_spans.gate(sym::const_trait_impl, span);
799             self.sess.emit_err(errors::ConstMissingTilde { span, start: span.shrink_to_lo() });
800 
801             Some(span)
802         } else {
803             None
804         };
805 
806         let bound_polarity = if self.eat(&token::Question) {
807             BoundPolarity::Maybe(self.prev_token.span)
808         } else if self.eat(&token::Not) {
809             self.sess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
810             BoundPolarity::Negative(self.prev_token.span)
811         } else {
812             BoundPolarity::Positive
813         };
814 
815         Ok(BoundModifiers { bound_polarity, maybe_const })
816     }
817 
818     /// Parses a type bound according to:
819     /// ```ebnf
820     /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
821     /// TY_BOUND_NOPAREN = [TY_BOUND_MODIFIERS] [for<LT_PARAM_DEFS>] SIMPLE_PATH
822     /// ```
823     ///
824     /// For example, this grammar accepts `~const ?for<'a: 'b> m::Trait<'a>`.
parse_generic_ty_bound( &mut self, lo: Span, has_parens: bool, modifiers: BoundModifiers, ) -> PResult<'a, GenericBound>825     fn parse_generic_ty_bound(
826         &mut self,
827         lo: Span,
828         has_parens: bool,
829         modifiers: BoundModifiers,
830     ) -> PResult<'a, GenericBound> {
831         let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?;
832         let mut path = if self.token.is_keyword(kw::Fn)
833             && self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
834             && let Some(path) = self.recover_path_from_fn()
835         {
836             path
837         } else if !self.token.is_path_start() && self.token.can_begin_type() {
838             let ty = self.parse_ty_no_plus()?;
839             // Instead of finding a path (a trait), we found a type.
840             let mut err = self.struct_span_err(ty.span, "expected a trait, found type");
841 
842             // If we can recover, try to extract a path from the type. Note
843             // that we do not use the try operator when parsing the type because
844             // if it fails then we get a parser error which we don't want (we're trying
845             // to recover from errors, not make more).
846             let path = if self.may_recover()
847                 && matches!(ty.kind, TyKind::Ptr(..) | TyKind::Ref(..))
848                 && let TyKind::Path(_, path) = &ty.peel_refs().kind {
849                 // Just get the indirection part of the type.
850                 let span = ty.span.until(path.span);
851 
852                 err.span_suggestion_verbose(
853                     span,
854                     "consider removing the indirection",
855                     "",
856                     Applicability::MaybeIncorrect,
857                 );
858 
859                 path.clone()
860             } else {
861                 return Err(err);
862             };
863 
864             err.emit();
865 
866             path
867         } else {
868             self.parse_path(PathStyle::Type)?
869         };
870 
871         if self.may_recover() && self.token == TokenKind::OpenDelim(Delimiter::Parenthesis) {
872             self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
873         }
874 
875         if has_parens {
876             if self.token.is_like_plus() {
877                 // Someone has written something like `&dyn (Trait + Other)`. The correct code
878                 // would be `&(dyn Trait + Other)`, but we don't have access to the appropriate
879                 // span to suggest that. When written as `&dyn Trait + Other`, an appropriate
880                 // suggestion is given.
881                 let bounds = vec![];
882                 self.parse_remaining_bounds(bounds, true)?;
883                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
884                 let sp = vec![lo, self.prev_token.span];
885                 self.sess.emit_err(errors::IncorrectBracesTraitBounds {
886                     span: sp,
887                     sugg: errors::IncorrectBracesTraitBoundsSugg { l: lo, r: self.prev_token.span },
888                 });
889             } else {
890                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
891             }
892         }
893 
894         let modifier = modifiers.to_trait_bound_modifier();
895         let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
896         Ok(GenericBound::Trait(poly_trait, modifier))
897     }
898 
899     // recovers a `Fn(..)` parenthesized-style path from `fn(..)`
recover_path_from_fn(&mut self) -> Option<ast::Path>900     fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
901         let fn_token_span = self.token.span;
902         self.bump();
903         let args_lo = self.token.span;
904         let snapshot = self.create_snapshot_for_diagnostic();
905         match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
906             Ok(decl) => {
907                 self.sess.emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
908                 Some(ast::Path {
909                     span: fn_token_span.to(self.prev_token.span),
910                     segments: thin_vec![ast::PathSegment {
911                         ident: Ident::new(Symbol::intern("Fn"), fn_token_span),
912                         id: DUMMY_NODE_ID,
913                         args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
914                             span: args_lo.to(self.prev_token.span),
915                             inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
916                             inputs_span: args_lo.until(decl.output.span()),
917                             output: decl.output.clone(),
918                         }))),
919                     }],
920                     tokens: None,
921                 })
922             }
923             Err(diag) => {
924                 diag.cancel();
925                 self.restore_snapshot(snapshot);
926                 None
927             }
928         }
929     }
930 
931     /// Optionally parses `for<$generic_params>`.
parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec<GenericParam>>932     pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec<GenericParam>> {
933         if self.eat_keyword(kw::For) {
934             self.expect_lt()?;
935             let params = self.parse_generic_params()?;
936             self.expect_gt()?;
937             // We rely on AST validation to rule out invalid cases: There must not be type
938             // parameters, and the lifetime parameters must not have bounds.
939             Ok(params)
940         } else {
941             Ok(ThinVec::new())
942         }
943     }
944 
945     /// Recover from `Fn`-family traits (Fn, FnMut, FnOnce) with lifetime arguments
946     /// (e.g. `FnOnce<'a>(&'a str) -> bool`). Up to generic arguments have already
947     /// been eaten.
recover_fn_trait_with_lifetime_params( &mut self, fn_path: &mut ast::Path, lifetime_defs: &mut ThinVec<GenericParam>, ) -> PResult<'a, ()>948     fn recover_fn_trait_with_lifetime_params(
949         &mut self,
950         fn_path: &mut ast::Path,
951         lifetime_defs: &mut ThinVec<GenericParam>,
952     ) -> PResult<'a, ()> {
953         let fn_path_segment = fn_path.segments.last_mut().unwrap();
954         let generic_args = if let Some(p_args) = &fn_path_segment.args {
955             p_args.clone().into_inner()
956         } else {
957             // Normally it wouldn't come here because the upstream should have parsed
958             // generic parameters (otherwise it's impossible to call this function).
959             return Ok(());
960         };
961         let lifetimes =
962             if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
963                 &generic_args
964             {
965                 args.into_iter()
966                     .filter_map(|arg| {
967                         if let ast::AngleBracketedArg::Arg(generic_arg) = arg
968                             && let ast::GenericArg::Lifetime(lifetime) = generic_arg {
969                             Some(lifetime)
970                         } else {
971                             None
972                         }
973                     })
974                     .collect()
975             } else {
976                 Vec::new()
977             };
978         // Only try to recover if the trait has lifetime params.
979         if lifetimes.is_empty() {
980             return Ok(());
981         }
982 
983         // Parse `(T, U) -> R`.
984         let inputs_lo = self.token.span;
985         let inputs: ThinVec<_> =
986             self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
987         let inputs_span = inputs_lo.to(self.prev_token.span);
988         let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
989         let args = ast::ParenthesizedArgs {
990             span: fn_path_segment.span().to(self.prev_token.span),
991             inputs,
992             inputs_span,
993             output,
994         }
995         .into();
996         *fn_path_segment = ast::PathSegment {
997             ident: fn_path_segment.ident,
998             args: Some(args),
999             id: ast::DUMMY_NODE_ID,
1000         };
1001 
1002         // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`.
1003         let mut generic_params = lifetimes
1004             .iter()
1005             .map(|lt| GenericParam {
1006                 id: lt.id,
1007                 ident: lt.ident,
1008                 attrs: ast::AttrVec::new(),
1009                 bounds: Vec::new(),
1010                 is_placeholder: false,
1011                 kind: ast::GenericParamKind::Lifetime,
1012                 colon_span: None,
1013             })
1014             .collect::<ThinVec<GenericParam>>();
1015         lifetime_defs.append(&mut generic_params);
1016 
1017         let generic_args_span = generic_args.span();
1018         let mut err =
1019             self.struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters");
1020         let snippet = format!(
1021             "for<{}> ",
1022             lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1023         );
1024         let before_fn_path = fn_path.span.shrink_to_lo();
1025         err.multipart_suggestion(
1026             "consider using a higher-ranked trait bound instead",
1027             vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1028             Applicability::MaybeIncorrect,
1029         )
1030         .emit();
1031         Ok(())
1032     }
1033 
check_lifetime(&mut self) -> bool1034     pub(super) fn check_lifetime(&mut self) -> bool {
1035         self.expected_tokens.push(TokenType::Lifetime);
1036         self.token.is_lifetime()
1037     }
1038 
1039     /// Parses a single lifetime `'a` or panics.
expect_lifetime(&mut self) -> Lifetime1040     pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1041         if let Some(ident) = self.token.lifetime() {
1042             self.bump();
1043             Lifetime { ident, id: ast::DUMMY_NODE_ID }
1044         } else {
1045             self.span_bug(self.token.span, "not a lifetime")
1046         }
1047     }
1048 
mk_ty(&self, span: Span, kind: TyKind) -> P<Ty>1049     pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
1050         P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1051     }
1052 }
1053