rustc_parse/parser/
ty.rs

1use rustc_ast::ptr::P;
2use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind};
3use rustc_ast::util::case::Case;
4use rustc_ast::{
5    self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
6    GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
7    Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
8    TyKind, UnsafeBinderTy,
9};
10use rustc_errors::{Applicability, PResult};
11use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
12use thin_vec::{ThinVec, thin_vec};
13
14use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
15use crate::errors::{
16    self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
17    FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
18    HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
19    NestedCVariadicType, ReturnTypesUseThinArrow,
20};
21use crate::{exp, maybe_recover_from_interpolated_ty_qpath, maybe_whole};
22
23/// Signals whether parsing a type should allow `+`.
24///
25/// For example, let T be the type `impl Default + 'static`
26/// With `AllowPlus::Yes`, T will be parsed successfully
27/// With `AllowPlus::No`, parsing T will return a parse error
28#[derive(Copy, Clone, PartialEq)]
29pub(super) enum AllowPlus {
30    Yes,
31    No,
32}
33
34#[derive(PartialEq)]
35pub(super) enum RecoverQPath {
36    Yes,
37    No,
38}
39
40pub(super) enum RecoverQuestionMark {
41    Yes,
42    No,
43}
44
45/// Signals whether parsing a type should recover `->`.
46///
47/// More specifically, when parsing a function like:
48/// ```compile_fail
49/// fn foo() => u8 { 0 }
50/// fn bar(): u8 { 0 }
51/// ```
52/// The compiler will try to recover interpreting `foo() => u8` as `foo() -> u8` when calling
53/// `parse_ty` with anything except `RecoverReturnSign::No`, and it will try to recover `bar(): u8`
54/// as `bar() -> u8` when passing `RecoverReturnSign::Yes` to `parse_ty`
55#[derive(Copy, Clone, PartialEq)]
56pub(super) enum RecoverReturnSign {
57    Yes,
58    OnlyFatArrow,
59    No,
60}
61
62impl RecoverReturnSign {
63    /// [RecoverReturnSign::Yes] allows for recovering `fn foo() => u8` and `fn foo(): u8`,
64    /// [RecoverReturnSign::OnlyFatArrow] allows for recovering only `fn foo() => u8` (recovering
65    /// colons can cause problems when parsing where clauses), and
66    /// [RecoverReturnSign::No] doesn't allow for any recovery of the return type arrow
67    fn can_recover(self, token: &TokenKind) -> bool {
68        match self {
69            Self::Yes => matches!(token, token::FatArrow | token::Colon),
70            Self::OnlyFatArrow => matches!(token, token::FatArrow),
71            Self::No => false,
72        }
73    }
74}
75
76// Is `...` (`CVarArgs`) legal at this level of type parsing?
77#[derive(PartialEq)]
78enum AllowCVariadic {
79    Yes,
80    No,
81}
82
83/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
84/// `IDENT<<u8 as Trait>::AssocTy>`.
85///
86/// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
87/// that `IDENT` is not the ident of a fn trait.
88fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
89    t == &token::PathSep || t == &token::Lt || t == &token::BinOp(token::Shl)
90}
91
92fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
93    // `Not`, `Tilde` & `Const` are deliberately not part of this list to
94    // contain the number of potential regressions esp. in MBE code.
95    // `Const` would regress `rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs`.
96    // `Not` would regress `dyn!(...)` macro calls in Rust 2015.
97    t.is_path_start()
98        || t.is_lifetime()
99        || t == &TokenKind::Question
100        || t.is_keyword(kw::For)
101        || t == &TokenKind::OpenDelim(Delimiter::Parenthesis)
102}
103
104impl<'a> Parser<'a> {
105    /// Parses a type.
106    pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
107        self.parse_ty_common(
108            AllowPlus::Yes,
109            AllowCVariadic::No,
110            RecoverQPath::Yes,
111            RecoverReturnSign::Yes,
112            None,
113            RecoverQuestionMark::Yes,
114        )
115    }
116
117    pub(super) fn parse_ty_with_generics_recovery(
118        &mut self,
119        ty_params: &Generics,
120    ) -> PResult<'a, P<Ty>> {
121        self.parse_ty_common(
122            AllowPlus::Yes,
123            AllowCVariadic::No,
124            RecoverQPath::Yes,
125            RecoverReturnSign::Yes,
126            Some(ty_params),
127            RecoverQuestionMark::Yes,
128        )
129    }
130
131    /// Parse a type suitable for a function or function pointer parameter.
132    /// The difference from `parse_ty` is that this version allows `...`
133    /// (`CVarArgs`) at the top level of the type.
134    pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
135        self.parse_ty_common(
136            AllowPlus::Yes,
137            AllowCVariadic::Yes,
138            RecoverQPath::Yes,
139            RecoverReturnSign::Yes,
140            None,
141            RecoverQuestionMark::Yes,
142        )
143    }
144
145    /// Parses a type in restricted contexts where `+` is not permitted.
146    ///
147    /// Example 1: `&'a TYPE`
148    ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
149    /// Example 2: `value1 as TYPE + value2`
150    ///     `+` is prohibited to avoid interactions with expression grammar.
151    pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
152        self.parse_ty_common(
153            AllowPlus::No,
154            AllowCVariadic::No,
155            RecoverQPath::Yes,
156            RecoverReturnSign::Yes,
157            None,
158            RecoverQuestionMark::Yes,
159        )
160    }
161
162    /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
163    /// for better diagnostics involving `?`.
164    pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
165        self.parse_ty_common(
166            AllowPlus::No,
167            AllowCVariadic::No,
168            RecoverQPath::Yes,
169            RecoverReturnSign::Yes,
170            None,
171            RecoverQuestionMark::No,
172        )
173    }
174
175    pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
176        self.parse_ty_common(
177            AllowPlus::Yes,
178            AllowCVariadic::No,
179            RecoverQPath::Yes,
180            RecoverReturnSign::Yes,
181            None,
182            RecoverQuestionMark::No,
183        )
184    }
185
186    /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
187    pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
188        self.parse_ty_common(
189            AllowPlus::Yes,
190            AllowCVariadic::No,
191            RecoverQPath::Yes,
192            RecoverReturnSign::OnlyFatArrow,
193            None,
194            RecoverQuestionMark::Yes,
195        )
196    }
197
198    /// Parses an optional return type `[ -> TY ]` in a function declaration.
199    pub(super) fn parse_ret_ty(
200        &mut self,
201        allow_plus: AllowPlus,
202        recover_qpath: RecoverQPath,
203        recover_return_sign: RecoverReturnSign,
204    ) -> PResult<'a, FnRetTy> {
205        let lo = self.prev_token.span;
206        Ok(if self.eat(exp!(RArrow)) {
207            // FIXME(Centril): Can we unconditionally `allow_plus`?
208            let ty = self.parse_ty_common(
209                allow_plus,
210                AllowCVariadic::No,
211                recover_qpath,
212                recover_return_sign,
213                None,
214                RecoverQuestionMark::Yes,
215            )?;
216            FnRetTy::Ty(ty)
217        } else if recover_return_sign.can_recover(&self.token.kind) {
218            // Don't `eat` to prevent `=>` from being added as an expected token which isn't
219            // actually expected and could only confuse users
220            self.bump();
221            self.dcx().emit_err(ReturnTypesUseThinArrow {
222                span: self.prev_token.span,
223                suggestion: lo.between(self.token.span),
224            });
225            let ty = self.parse_ty_common(
226                allow_plus,
227                AllowCVariadic::No,
228                recover_qpath,
229                recover_return_sign,
230                None,
231                RecoverQuestionMark::Yes,
232            )?;
233            FnRetTy::Ty(ty)
234        } else {
235            FnRetTy::Default(self.prev_token.span.shrink_to_hi())
236        })
237    }
238
239    fn parse_ty_common(
240        &mut self,
241        allow_plus: AllowPlus,
242        allow_c_variadic: AllowCVariadic,
243        recover_qpath: RecoverQPath,
244        recover_return_sign: RecoverReturnSign,
245        ty_generics: Option<&Generics>,
246        recover_question_mark: RecoverQuestionMark,
247    ) -> PResult<'a, P<Ty>> {
248        let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
249        maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
250        maybe_whole!(self, NtTy, |ty| ty);
251
252        let lo = self.token.span;
253        let mut impl_dyn_multi = false;
254        let kind = if self.check(exp!(OpenParen)) {
255            self.parse_ty_tuple_or_parens(lo, allow_plus)?
256        } else if self.eat(exp!(Not)) {
257            // Never type `!`
258            TyKind::Never
259        } else if self.eat(exp!(Star)) {
260            self.parse_ty_ptr()?
261        } else if self.eat(exp!(OpenBracket)) {
262            self.parse_array_or_slice_ty()?
263        } else if self.check(exp!(And)) || self.check(exp!(AndAnd)) {
264            // Reference
265            self.expect_and()?;
266            self.parse_borrowed_pointee()?
267        } else if self.eat_keyword_noexpect(kw::Typeof) {
268            self.parse_typeof_ty()?
269        } else if self.eat_keyword(exp!(Underscore)) {
270            // A type to be inferred `_`
271            TyKind::Infer
272        } else if self.check_fn_front_matter(false, Case::Sensitive) {
273            // Function pointer type
274            self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)?
275        } else if self.check_keyword(exp!(For)) {
276            // Function pointer type or bound list (trait object type) starting with a poly-trait.
277            //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
278            //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
279            let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?;
280            if self.check_fn_front_matter(false, Case::Sensitive) {
281                self.parse_ty_bare_fn(
282                    lo,
283                    lifetime_defs,
284                    Some(self.prev_token.span.shrink_to_lo()),
285                    recover_return_sign,
286                )?
287            } else {
288                // Try to recover `for<'a> dyn Trait` or `for<'a> impl Trait`.
289                if self.may_recover()
290                    && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn))
291                {
292                    let kw = self.prev_token.ident().unwrap().0;
293                    let removal_span = kw.span.with_hi(self.token.span.lo());
294                    let path = self.parse_path(PathStyle::Type)?;
295                    let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
296                    let kind =
297                        self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?;
298                    let err = self.dcx().create_err(errors::TransposeDynOrImpl {
299                        span: kw.span,
300                        kw: kw.name.as_str(),
301                        sugg: errors::TransposeDynOrImplSugg {
302                            removal_span,
303                            insertion_span: lo.shrink_to_lo(),
304                            kw: kw.name.as_str(),
305                        },
306                    });
307
308                    // Take the parsed bare trait object and turn it either
309                    // into a `dyn` object or an `impl Trait`.
310                    let kind = match (kind, kw.name) {
311                        (TyKind::TraitObject(bounds, _), kw::Dyn) => {
312                            TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
313                        }
314                        (TyKind::TraitObject(bounds, _), kw::Impl) => {
315                            TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
316                        }
317                        _ => return Err(err),
318                    };
319                    err.emit();
320                    kind
321                } else {
322                    let path = self.parse_path(PathStyle::Type)?;
323                    let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
324                    self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
325                }
326            }
327        } else if self.eat_keyword(exp!(Impl)) {
328            self.parse_impl_ty(&mut impl_dyn_multi)?
329        } else if self.is_explicit_dyn_type() {
330            self.parse_dyn_ty(&mut impl_dyn_multi)?
331        } else if self.eat_lt() {
332            // Qualified path
333            let (qself, path) = self.parse_qpath(PathStyle::Type)?;
334            TyKind::Path(Some(qself), path)
335        } else if self.check_path() {
336            self.parse_path_start_ty(lo, allow_plus, ty_generics)?
337        } else if self.can_begin_bound() {
338            self.parse_bare_trait_object(lo, allow_plus)?
339        } else if self.eat(exp!(DotDotDot)) {
340            match allow_c_variadic {
341                AllowCVariadic::Yes => TyKind::CVarArgs,
342                AllowCVariadic::No => {
343                    // FIXME(c_variadic): Should we just allow `...` syntactically
344                    // anywhere in a type and use semantic restrictions instead?
345                    // NOTE: This may regress certain MBE calls if done incorrectly.
346                    let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
347                    TyKind::Err(guar)
348                }
349            }
350        } else if self.check_keyword(exp!(Unsafe))
351            && self.look_ahead(1, |tok| matches!(tok.kind, token::Lt))
352        {
353            self.parse_unsafe_binder_ty()?
354        } else {
355            let msg = format!("expected type, found {}", super::token_descr(&self.token));
356            let mut err = self.dcx().struct_span_err(lo, msg);
357            err.span_label(lo, "expected type");
358            return Err(err);
359        };
360
361        let span = lo.to(self.prev_token.span);
362        let mut ty = self.mk_ty(span, kind);
363
364        // Try to recover from use of `+` with incorrect priority.
365        match allow_plus {
366            AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
367            AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
368        }
369        if let RecoverQuestionMark::Yes = recover_question_mark {
370            ty = self.maybe_recover_from_question_mark(ty);
371        }
372        if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
373    }
374
375    fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
376        let lo = self.token.span;
377        assert!(self.eat_keyword(exp!(Unsafe)));
378        self.expect_lt()?;
379        let generic_params = self.parse_generic_params()?;
380        self.expect_gt()?;
381        let inner_ty = self.parse_ty()?;
382        let span = lo.to(self.prev_token.span);
383        self.psess.gated_spans.gate(sym::unsafe_binders, span);
384
385        Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
386    }
387
388    /// Parses either:
389    /// - `(TYPE)`, a parenthesized type.
390    /// - `(TYPE,)`, a tuple with a single field of type TYPE.
391    fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
392        let mut trailing_plus = false;
393        let (ts, trailing) = self.parse_paren_comma_seq(|p| {
394            let ty = p.parse_ty()?;
395            trailing_plus = p.prev_token == TokenKind::BinOp(token::Plus);
396            Ok(ty)
397        })?;
398
399        if ts.len() == 1 && matches!(trailing, Trailing::No) {
400            let ty = ts.into_iter().next().unwrap().into_inner();
401            let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
402            match ty.kind {
403                // `(TY_BOUND_NOPAREN) + BOUND + ...`.
404                TyKind::Path(None, path) if maybe_bounds => {
405                    self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
406                }
407                TyKind::TraitObject(bounds, TraitObjectSyntax::None)
408                    if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
409                {
410                    self.parse_remaining_bounds(bounds, true)
411                }
412                // `(TYPE)`
413                _ => Ok(TyKind::Paren(P(ty))),
414            }
415        } else {
416            Ok(TyKind::Tup(ts))
417        }
418    }
419
420    fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
421        let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
422        let bounds = self.parse_generic_bounds_common(allow_plus)?;
423        if lt_no_plus {
424            self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime { span: lo });
425        }
426        Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
427    }
428
429    fn parse_remaining_bounds_path(
430        &mut self,
431        generic_params: ThinVec<GenericParam>,
432        path: ast::Path,
433        lo: Span,
434        parse_plus: bool,
435    ) -> PResult<'a, TyKind> {
436        let poly_trait_ref = PolyTraitRef::new(
437            generic_params,
438            path,
439            TraitBoundModifiers::NONE,
440            lo.to(self.prev_token.span),
441        );
442        let bounds = vec![GenericBound::Trait(poly_trait_ref)];
443        self.parse_remaining_bounds(bounds, parse_plus)
444    }
445
446    /// Parse the remainder of a bare trait object type given an already parsed list.
447    fn parse_remaining_bounds(
448        &mut self,
449        mut bounds: GenericBounds,
450        plus: bool,
451    ) -> PResult<'a, TyKind> {
452        if plus {
453            self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
454            bounds.append(&mut self.parse_generic_bounds()?);
455        }
456        Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
457    }
458
459    /// Parses a raw pointer type: `*[const | mut] $type`.
460    fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
461        let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
462            let span = self.prev_token.span;
463            self.dcx().emit_err(ExpectedMutOrConstInRawPointerType {
464                span,
465                after_asterisk: span.shrink_to_hi(),
466            });
467            Mutability::Not
468        });
469        let ty = self.parse_ty_no_plus()?;
470        Ok(TyKind::Ptr(MutTy { ty, mutbl }))
471    }
472
473    /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
474    /// The opening `[` bracket is already eaten.
475    fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
476        let elt_ty = match self.parse_ty() {
477            Ok(ty) => ty,
478            Err(err)
479                if self.look_ahead(1, |t| *t == token::CloseDelim(Delimiter::Bracket))
480                    | self.look_ahead(1, |t| *t == token::Semi) =>
481            {
482                // Recover from `[LIT; EXPR]` and `[LIT]`
483                self.bump();
484                let guar = err.emit();
485                self.mk_ty(self.prev_token.span, TyKind::Err(guar))
486            }
487            Err(err) => return Err(err),
488        };
489
490        let ty = if self.eat(exp!(Semi)) {
491            let mut length = self.parse_expr_anon_const()?;
492            if let Err(e) = self.expect(exp!(CloseBracket)) {
493                // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
494                self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
495                self.expect(exp!(CloseBracket))?;
496            }
497            TyKind::Array(elt_ty, length)
498        } else {
499            self.expect(exp!(CloseBracket))?;
500            TyKind::Slice(elt_ty)
501        };
502
503        Ok(ty)
504    }
505
506    fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
507        let and_span = self.prev_token.span;
508        let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
509        let (pinned, mut mutbl) = match self.parse_pin_and_mut() {
510            Some(pin_mut) => pin_mut,
511            None => (Pinnedness::Not, self.parse_mutability()),
512        };
513        if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
514            // A lifetime is invalid here: it would be part of a bare trait bound, which requires
515            // it to be followed by a plus, but we disallow plus in the pointee type.
516            // So we can handle this case as an error here, and suggest `'a mut`.
517            // If there *is* a plus next though, handling the error later provides better suggestions
518            // (like adding parentheses)
519            if !self.look_ahead(1, |t| t.is_like_plus()) {
520                let lifetime_span = self.token.span;
521                let span = and_span.to(lifetime_span);
522
523                let (suggest_lifetime, snippet) =
524                    if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
525                        (Some(span), lifetime_src)
526                    } else {
527                        (None, String::new())
528                    };
529                self.dcx().emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
530
531                opt_lifetime = Some(self.expect_lifetime());
532            }
533        } else if self.token.is_keyword(kw::Dyn)
534            && mutbl == Mutability::Not
535            && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
536        {
537            // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
538            let span = and_span.to(self.look_ahead(1, |t| t.span));
539            self.dcx().emit_err(DynAfterMut { span });
540
541            // Recovery
542            mutbl = Mutability::Mut;
543            let (dyn_tok, dyn_tok_sp) = (self.token.clone(), self.token_spacing);
544            self.bump();
545            self.bump_with((dyn_tok, dyn_tok_sp));
546        }
547        let ty = self.parse_ty_no_plus()?;
548        Ok(match pinned {
549            Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
550            Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
551        })
552    }
553
554    /// Parses `pin` and `mut` annotations on references.
555    ///
556    /// It must be either `pin const` or `pin mut`.
557    pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> {
558        if self.token.is_ident_named(sym::pin) {
559            let result = self.look_ahead(1, |token| {
560                if token.is_keyword(kw::Const) {
561                    Some((Pinnedness::Pinned, Mutability::Not))
562                } else if token.is_keyword(kw::Mut) {
563                    Some((Pinnedness::Pinned, Mutability::Mut))
564                } else {
565                    None
566                }
567            });
568            if result.is_some() {
569                self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
570                self.bump();
571                self.bump();
572            }
573            result
574        } else {
575            None
576        }
577    }
578
579    // Parses the `typeof(EXPR)`.
580    // To avoid ambiguity, the type is surrounded by parentheses.
581    fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
582        self.expect(exp!(OpenParen))?;
583        let expr = self.parse_expr_anon_const()?;
584        self.expect(exp!(CloseParen))?;
585        Ok(TyKind::Typeof(expr))
586    }
587
588    /// Parses a function pointer type (`TyKind::BareFn`).
589    /// ```ignore (illustrative)
590    ///    [unsafe] [extern "ABI"] fn (S) -> T
591    /// //  ^~~~~^          ^~~~^     ^~^    ^
592    /// //    |               |        |     |
593    /// //    |               |        |   Return type
594    /// // Function Style    ABI  Parameter types
595    /// ```
596    /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
597    fn parse_ty_bare_fn(
598        &mut self,
599        lo: Span,
600        mut params: ThinVec<GenericParam>,
601        param_insertion_point: Option<Span>,
602        recover_return_sign: RecoverReturnSign,
603    ) -> PResult<'a, TyKind> {
604        let inherited_vis = rustc_ast::Visibility {
605            span: rustc_span::DUMMY_SP,
606            kind: rustc_ast::VisibilityKind::Inherited,
607            tokens: None,
608        };
609        let span_start = self.token.span;
610        let ast::FnHeader { ext, safety, constness, coroutine_kind } =
611            self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
612        let fn_start_lo = self.prev_token.span.lo();
613        if self.may_recover() && self.token == TokenKind::Lt {
614            self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
615        }
616        let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
617        let whole_span = lo.to(self.prev_token.span);
618
619        // Order/parsing of "front matter" follows:
620        // `<constness> <coroutine_kind> <safety> <extern> fn()`
621        //  ^           ^                ^        ^        ^
622        //  |           |                |        |        fn_start_lo
623        //  |           |                |        ext_sp.lo
624        //  |           |                safety_sp.lo
625        //  |           coroutine_sp.lo
626        //  const_sp.lo
627        if let ast::Const::Yes(const_span) = constness {
628            let next_token_lo = if let Some(
629                ast::CoroutineKind::Async { span, .. }
630                | ast::CoroutineKind::Gen { span, .. }
631                | ast::CoroutineKind::AsyncGen { span, .. },
632            ) = coroutine_kind
633            {
634                span.lo()
635            } else if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety {
636                span.lo()
637            } else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
638                span.lo()
639            } else {
640                fn_start_lo
641            };
642            let sugg_span = const_span.with_hi(next_token_lo);
643            self.dcx().emit_err(FnPointerCannotBeConst {
644                span: whole_span,
645                qualifier: const_span,
646                suggestion: sugg_span,
647            });
648        }
649        if let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind {
650            let next_token_lo = if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety
651            {
652                span.lo()
653            } else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
654                span.lo()
655            } else {
656                fn_start_lo
657            };
658            let sugg_span = async_span.with_hi(next_token_lo);
659            self.dcx().emit_err(FnPointerCannotBeAsync {
660                span: whole_span,
661                qualifier: async_span,
662                suggestion: sugg_span,
663            });
664        }
665        // FIXME(gen_blocks): emit a similar error for `gen fn()`
666        let decl_span = span_start.to(self.prev_token.span);
667        Ok(TyKind::BareFn(P(BareFnTy { ext, safety, generic_params: params, decl, decl_span })))
668    }
669
670    /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
671    fn recover_fn_ptr_with_generics(
672        &mut self,
673        lo: Span,
674        params: &mut ThinVec<GenericParam>,
675        param_insertion_point: Option<Span>,
676    ) -> PResult<'a, ()> {
677        let generics = self.parse_generics()?;
678        let arity = generics.params.len();
679
680        let mut lifetimes: ThinVec<_> = generics
681            .params
682            .into_iter()
683            .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
684            .collect();
685
686        let sugg = if !lifetimes.is_empty() {
687            let snippet =
688                lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
689
690            let (left, snippet) = if let Some(span) = param_insertion_point {
691                (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
692            } else {
693                (lo.shrink_to_lo(), format!("for<{snippet}> "))
694            };
695
696            Some(FnPtrWithGenericsSugg {
697                left,
698                snippet,
699                right: generics.span,
700                arity,
701                for_param_list_exists: param_insertion_point.is_some(),
702            })
703        } else {
704            None
705        };
706
707        self.dcx().emit_err(FnPtrWithGenerics { span: generics.span, sugg });
708        params.append(&mut lifetimes);
709        Ok(())
710    }
711
712    /// Parses an `impl B0 + ... + Bn` type.
713    fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
714        if self.token.is_lifetime() {
715            self.look_ahead(1, |t| {
716                if let token::Ident(sym, _) = t.kind {
717                    // parse pattern with "'a Sized" we're supposed to give suggestion like
718                    // "'a + Sized"
719                    self.dcx().emit_err(errors::MissingPlusBounds {
720                        span: self.token.span,
721                        hi: self.token.span.shrink_to_hi(),
722                        sym,
723                    });
724                }
725            })
726        }
727
728        // Always parse bounds greedily for better error recovery.
729        let bounds = self.parse_generic_bounds()?;
730
731        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus);
732
733        Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
734    }
735
736    fn parse_precise_capturing_args(
737        &mut self,
738    ) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
739        let lo = self.token.span;
740        self.expect_lt()?;
741        let (args, _, _) = self.parse_seq_to_before_tokens(
742            &[exp!(Gt)],
743            &[
744                &TokenKind::Ge,
745                &TokenKind::BinOp(BinOpToken::Shr),
746                &TokenKind::BinOpEq(BinOpToken::Shr),
747            ],
748            SeqSep::trailing_allowed(exp!(Comma)),
749            |self_| {
750                if self_.check_keyword(exp!(SelfUpper)) {
751                    self_.bump();
752                    Ok(PreciseCapturingArg::Arg(
753                        ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
754                        DUMMY_NODE_ID,
755                    ))
756                } else if self_.check_ident() {
757                    Ok(PreciseCapturingArg::Arg(
758                        ast::Path::from_ident(self_.parse_ident()?),
759                        DUMMY_NODE_ID,
760                    ))
761                } else if self_.check_lifetime() {
762                    Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
763                } else {
764                    self_.unexpected_any()
765                }
766            },
767        )?;
768        self.expect_gt()?;
769        Ok((args, lo.to(self.prev_token.span)))
770    }
771
772    /// Is a `dyn B0 + ... + Bn` type allowed here?
773    fn is_explicit_dyn_type(&mut self) -> bool {
774        self.check_keyword(exp!(Dyn))
775            && (self.token.uninterpolated_span().at_least_rust_2018()
776                || self.look_ahead(1, |t| {
777                    (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::BinOp(token::Star))
778                        && !can_continue_type_after_non_fn_ident(t)
779                }))
780    }
781
782    /// Parses a `dyn B0 + ... + Bn` type.
783    ///
784    /// Note that this does *not* parse bare trait objects.
785    fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
786        let lo = self.token.span;
787        self.bump(); // `dyn`
788
789        // parse dyn* types
790        let syntax = if self.eat(exp!(Star)) {
791            self.psess.gated_spans.gate(sym::dyn_star, lo.to(self.prev_token.span));
792            TraitObjectSyntax::DynStar
793        } else {
794            TraitObjectSyntax::Dyn
795        };
796
797        // Always parse bounds greedily for better error recovery.
798        let bounds = self.parse_generic_bounds()?;
799        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus);
800        Ok(TyKind::TraitObject(bounds, syntax))
801    }
802
803    /// Parses a type starting with a path.
804    ///
805    /// This can be:
806    /// 1. a type macro, `mac!(...)`,
807    /// 2. a bare trait object, `B0 + ... + Bn`,
808    /// 3. or a path, `path::to::MyType`.
809    fn parse_path_start_ty(
810        &mut self,
811        lo: Span,
812        allow_plus: AllowPlus,
813        ty_generics: Option<&Generics>,
814    ) -> PResult<'a, TyKind> {
815        // Simple path
816        let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
817        if self.eat(exp!(Not)) {
818            // Macro invocation in type position
819            Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
820        } else if allow_plus == AllowPlus::Yes && self.check_plus() {
821            // `Trait1 + Trait2 + 'a`
822            self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
823        } else {
824            // Just a type path.
825            Ok(TyKind::Path(None, path))
826        }
827    }
828
829    pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
830        self.parse_generic_bounds_common(AllowPlus::Yes)
831    }
832
833    /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
834    ///
835    /// See `parse_generic_bound` for the `BOUND` grammar.
836    fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
837        let mut bounds = Vec::new();
838
839        // In addition to looping while we find generic bounds:
840        // We continue even if we find a keyword. This is necessary for error recovery on,
841        // for example, `impl fn()`. The only keyword that can go after generic bounds is
842        // `where`, so stop if it's it.
843        // We also continue if we find types (not traits), again for error recovery.
844        while self.can_begin_bound()
845            || (self.may_recover()
846                && (self.token.can_begin_type()
847                    || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
848        {
849            if self.token.is_keyword(kw::Dyn) {
850                // Account for `&dyn Trait + dyn Other`.
851                self.bump();
852                self.dcx().emit_err(InvalidDynKeyword {
853                    span: self.prev_token.span,
854                    suggestion: self.prev_token.span.until(self.token.span),
855                });
856            }
857            bounds.push(self.parse_generic_bound()?);
858            if allow_plus == AllowPlus::No || !self.eat_plus() {
859                break;
860            }
861        }
862
863        Ok(bounds)
864    }
865
866    /// Can the current token begin a bound?
867    fn can_begin_bound(&mut self) -> bool {
868        self.check_path()
869            || self.check_lifetime()
870            || self.check(exp!(Not))
871            || self.check(exp!(Question))
872            || self.check(exp!(Tilde))
873            || self.check_keyword(exp!(For))
874            || self.check(exp!(OpenParen))
875            || self.check_keyword(exp!(Const))
876            || self.check_keyword(exp!(Async))
877            || self.check_keyword(exp!(Use))
878    }
879
880    /// Parses a bound according to the grammar:
881    /// ```ebnf
882    /// BOUND = TY_BOUND | LT_BOUND
883    /// ```
884    fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
885        let lo = self.token.span;
886        let leading_token = self.prev_token.clone();
887        let has_parens = self.eat(exp!(OpenParen));
888
889        let bound = if self.token.is_lifetime() {
890            self.parse_generic_lt_bound(lo, has_parens)?
891        } else if self.eat_keyword(exp!(Use)) {
892            // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of
893            // lifetimes and ident params (including SelfUpper). These are validated later
894            // for order, duplication, and whether they actually reference params.
895            let use_span = self.prev_token.span;
896            let (args, args_span) = self.parse_precise_capturing_args()?;
897            GenericBound::Use(args, use_span.to(args_span))
898        } else {
899            self.parse_generic_ty_bound(lo, has_parens, &leading_token)?
900        };
901
902        Ok(bound)
903    }
904
905    /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
906    /// ```ebnf
907    /// LT_BOUND = LIFETIME
908    /// ```
909    fn parse_generic_lt_bound(&mut self, lo: Span, has_parens: bool) -> PResult<'a, GenericBound> {
910        let lt = self.expect_lifetime();
911        let bound = GenericBound::Outlives(lt);
912        if has_parens {
913            // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
914            // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
915            self.recover_paren_lifetime(lo)?;
916        }
917        Ok(bound)
918    }
919
920    /// Emits an error if any trait bound modifiers were present.
921    fn error_lt_bound_with_modifiers(
922        &self,
923        modifiers: TraitBoundModifiers,
924        binder_span: Option<Span>,
925    ) -> ErrorGuaranteed {
926        let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
927
928        match constness {
929            BoundConstness::Never => {}
930            BoundConstness::Always(span) | BoundConstness::Maybe(span) => {
931                return self
932                    .dcx()
933                    .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() });
934            }
935        }
936
937        match polarity {
938            BoundPolarity::Positive => {}
939            BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
940                return self
941                    .dcx()
942                    .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() });
943            }
944        }
945
946        match asyncness {
947            BoundAsyncness::Normal => {}
948            BoundAsyncness::Async(span) => {
949                return self
950                    .dcx()
951                    .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() });
952            }
953        }
954
955        if let Some(span) = binder_span {
956            return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" });
957        }
958
959        unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
960    }
961
962    /// Recover on `('lifetime)` with `(` already eaten.
963    fn recover_paren_lifetime(&mut self, lo: Span) -> PResult<'a, ()> {
964        self.expect(exp!(CloseParen))?;
965        let span = lo.to(self.prev_token.span);
966        let sugg = errors::RemoveParens { lo, hi: self.prev_token.span };
967
968        self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg });
969        Ok(())
970    }
971
972    /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `~const Trait`.
973    ///
974    /// If no modifiers are present, this does not consume any tokens.
975    ///
976    /// ```ebnf
977    /// CONSTNESS = [["~"] "const"]
978    /// ASYNCNESS = ["async"]
979    /// POLARITY = ["?" | "!"]
980    /// ```
981    ///
982    /// See `parse_generic_ty_bound` for the complete grammar of trait bound modifiers.
983    fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
984        let modifier_lo = self.token.span;
985        let constness = if self.eat(exp!(Tilde)) {
986            let tilde = self.prev_token.span;
987            self.expect_keyword(exp!(Const))?;
988            let span = tilde.to(self.prev_token.span);
989            self.psess.gated_spans.gate(sym::const_trait_impl, span);
990            BoundConstness::Maybe(span)
991        } else if self.eat_keyword(exp!(Const)) {
992            self.psess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span);
993            BoundConstness::Always(self.prev_token.span)
994        } else {
995            BoundConstness::Never
996        };
997
998        let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
999            && self.eat_keyword(exp!(Async))
1000        {
1001            self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1002            BoundAsyncness::Async(self.prev_token.span)
1003        } else if self.may_recover()
1004            && self.token.uninterpolated_span().is_rust_2015()
1005            && self.is_kw_followed_by_ident(kw::Async)
1006        {
1007            self.bump(); // eat `async`
1008            self.dcx().emit_err(errors::AsyncBoundModifierIn2015 {
1009                span: self.prev_token.span,
1010                help: HelpUseLatestEdition::new(),
1011            });
1012            self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1013            BoundAsyncness::Async(self.prev_token.span)
1014        } else {
1015            BoundAsyncness::Normal
1016        };
1017        let modifier_hi = self.prev_token.span;
1018
1019        let polarity = if self.eat(exp!(Question)) {
1020            BoundPolarity::Maybe(self.prev_token.span)
1021        } else if self.eat(exp!(Not)) {
1022            self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
1023            BoundPolarity::Negative(self.prev_token.span)
1024        } else {
1025            BoundPolarity::Positive
1026        };
1027
1028        // Enforce the mutual-exclusivity of `const`/`async` and `?`/`!`.
1029        match polarity {
1030            BoundPolarity::Positive => {
1031                // All trait bound modifiers allowed to combine with positive polarity
1032            }
1033            BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1034                match (asyncness, constness) {
1035                    (BoundAsyncness::Normal, BoundConstness::Never) => {
1036                        // Ok, no modifiers.
1037                    }
1038                    (_, _) => {
1039                        let constness = constness.as_str();
1040                        let asyncness = asyncness.as_str();
1041                        let glue =
1042                            if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
1043                        let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
1044                        self.dcx().emit_err(errors::PolarityAndModifiers {
1045                            polarity_span,
1046                            polarity: polarity.as_str(),
1047                            modifiers_span: modifier_lo.to(modifier_hi),
1048                            modifiers_concatenated,
1049                        });
1050                    }
1051                }
1052            }
1053        }
1054
1055        Ok(TraitBoundModifiers { constness, asyncness, polarity })
1056    }
1057
1058    /// Parses a type bound according to:
1059    /// ```ebnf
1060    /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
1061    /// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
1062    /// ```
1063    ///
1064    /// For example, this grammar accepts `for<'a: 'b> ~const ?m::Trait<'a>`.
1065    fn parse_generic_ty_bound(
1066        &mut self,
1067        lo: Span,
1068        has_parens: bool,
1069        leading_token: &Token,
1070    ) -> PResult<'a, GenericBound> {
1071        let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
1072
1073        let modifiers_lo = self.token.span;
1074        let modifiers = self.parse_trait_bound_modifiers()?;
1075        let modifiers_span = modifiers_lo.to(self.prev_token.span);
1076
1077        if let Some(binder_span) = binder_span {
1078            match modifiers.polarity {
1079                BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1080                    self.dcx().emit_err(errors::BinderAndPolarity {
1081                        binder_span,
1082                        polarity_span,
1083                        polarity: modifiers.polarity.as_str(),
1084                    });
1085                }
1086                BoundPolarity::Positive => {}
1087            }
1088        }
1089
1090        // Recover erroneous lifetime bound with modifiers or binder.
1091        // e.g. `T: for<'a> 'a` or `T: ~const 'a`.
1092        if self.token.is_lifetime() {
1093            let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
1094            return self.parse_generic_lt_bound(lo, has_parens);
1095        }
1096
1097        if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
1098            lifetime_defs.extend(more_lifetime_defs);
1099            self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
1100        }
1101
1102        let mut path = if self.token.is_keyword(kw::Fn)
1103            && self.look_ahead(1, |t| *t == TokenKind::OpenDelim(Delimiter::Parenthesis))
1104            && let Some(path) = self.recover_path_from_fn()
1105        {
1106            path
1107        } else if !self.token.is_path_start() && self.token.can_begin_type() {
1108            let ty = self.parse_ty_no_plus()?;
1109            // Instead of finding a path (a trait), we found a type.
1110            let mut err = self.dcx().struct_span_err(ty.span, "expected a trait, found type");
1111
1112            // If we can recover, try to extract a path from the type. Note
1113            // that we do not use the try operator when parsing the type because
1114            // if it fails then we get a parser error which we don't want (we're trying
1115            // to recover from errors, not make more).
1116            let path = if self.may_recover() {
1117                let (span, message, sugg, path, applicability) = match &ty.kind {
1118                    TyKind::Ptr(..) | TyKind::Ref(..)
1119                        if let TyKind::Path(_, path) = &ty.peel_refs().kind =>
1120                    {
1121                        (
1122                            ty.span.until(path.span),
1123                            "consider removing the indirection",
1124                            "",
1125                            path,
1126                            Applicability::MaybeIncorrect,
1127                        )
1128                    }
1129                    TyKind::ImplTrait(_, bounds)
1130                        if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
1131                    {
1132                        (
1133                            ty.span.until(tr.span),
1134                            "use the trait bounds directly",
1135                            "",
1136                            &tr.trait_ref.path,
1137                            Applicability::MachineApplicable,
1138                        )
1139                    }
1140                    _ => return Err(err),
1141                };
1142
1143                err.span_suggestion_verbose(span, message, sugg, applicability);
1144
1145                path.clone()
1146            } else {
1147                return Err(err);
1148            };
1149
1150            err.emit();
1151
1152            path
1153        } else {
1154            self.parse_path(PathStyle::Type)?
1155        };
1156
1157        if self.may_recover() && self.token == TokenKind::OpenDelim(Delimiter::Parenthesis) {
1158            self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
1159        }
1160
1161        if has_parens {
1162            // Someone has written something like `&dyn (Trait + Other)`. The correct code
1163            // would be `&(dyn Trait + Other)`
1164            if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1165                let bounds = vec![];
1166                self.parse_remaining_bounds(bounds, true)?;
1167                self.expect(exp!(CloseParen))?;
1168                self.dcx().emit_err(errors::IncorrectParensTraitBounds {
1169                    span: vec![lo, self.prev_token.span],
1170                    sugg: errors::IncorrectParensTraitBoundsSugg {
1171                        wrong_span: leading_token.span.shrink_to_hi().to(lo),
1172                        new_span: leading_token.span.shrink_to_lo(),
1173                    },
1174                });
1175            } else {
1176                self.expect(exp!(CloseParen))?;
1177            }
1178        }
1179
1180        let poly_trait =
1181            PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
1182        Ok(GenericBound::Trait(poly_trait))
1183    }
1184
1185    // recovers a `Fn(..)` parenthesized-style path from `fn(..)`
1186    fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1187        let fn_token_span = self.token.span;
1188        self.bump();
1189        let args_lo = self.token.span;
1190        let snapshot = self.create_snapshot_for_diagnostic();
1191        match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1192            Ok(decl) => {
1193                self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1194                Some(ast::Path {
1195                    span: fn_token_span.to(self.prev_token.span),
1196                    segments: thin_vec![ast::PathSegment {
1197                        ident: Ident::new(sym::Fn, fn_token_span),
1198                        id: DUMMY_NODE_ID,
1199                        args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
1200                            span: args_lo.to(self.prev_token.span),
1201                            inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
1202                            inputs_span: args_lo.until(decl.output.span()),
1203                            output: decl.output.clone(),
1204                        }))),
1205                    }],
1206                    tokens: None,
1207                })
1208            }
1209            Err(diag) => {
1210                diag.cancel();
1211                self.restore_snapshot(snapshot);
1212                None
1213            }
1214        }
1215    }
1216
1217    /// Optionally parses `for<$generic_params>`.
1218    pub(super) fn parse_late_bound_lifetime_defs(
1219        &mut self,
1220    ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
1221        if self.eat_keyword(exp!(For)) {
1222            let lo = self.token.span;
1223            self.expect_lt()?;
1224            let params = self.parse_generic_params()?;
1225            self.expect_gt()?;
1226            // We rely on AST validation to rule out invalid cases: There must not be
1227            // type or const parameters, and parameters must not have bounds.
1228            Ok((params, Some(lo.to(self.prev_token.span))))
1229        } else {
1230            Ok((ThinVec::new(), None))
1231        }
1232    }
1233
1234    /// Recover from `Fn`-family traits (Fn, FnMut, FnOnce) with lifetime arguments
1235    /// (e.g. `FnOnce<'a>(&'a str) -> bool`). Up to generic arguments have already
1236    /// been eaten.
1237    fn recover_fn_trait_with_lifetime_params(
1238        &mut self,
1239        fn_path: &mut ast::Path,
1240        lifetime_defs: &mut ThinVec<GenericParam>,
1241    ) -> PResult<'a, ()> {
1242        let fn_path_segment = fn_path.segments.last_mut().unwrap();
1243        let generic_args = if let Some(p_args) = &fn_path_segment.args {
1244            p_args.clone().into_inner()
1245        } else {
1246            // Normally it wouldn't come here because the upstream should have parsed
1247            // generic parameters (otherwise it's impossible to call this function).
1248            return Ok(());
1249        };
1250        let lifetimes =
1251            if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1252                &generic_args
1253            {
1254                args.into_iter()
1255                    .filter_map(|arg| {
1256                        if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1257                            && let ast::GenericArg::Lifetime(lifetime) = generic_arg
1258                        {
1259                            Some(lifetime)
1260                        } else {
1261                            None
1262                        }
1263                    })
1264                    .collect()
1265            } else {
1266                Vec::new()
1267            };
1268        // Only try to recover if the trait has lifetime params.
1269        if lifetimes.is_empty() {
1270            return Ok(());
1271        }
1272
1273        // Parse `(T, U) -> R`.
1274        let inputs_lo = self.token.span;
1275        let inputs: ThinVec<_> =
1276            self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
1277        let inputs_span = inputs_lo.to(self.prev_token.span);
1278        let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
1279        let args = ast::ParenthesizedArgs {
1280            span: fn_path_segment.span().to(self.prev_token.span),
1281            inputs,
1282            inputs_span,
1283            output,
1284        }
1285        .into();
1286        *fn_path_segment = ast::PathSegment {
1287            ident: fn_path_segment.ident,
1288            args: Some(args),
1289            id: ast::DUMMY_NODE_ID,
1290        };
1291
1292        // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`.
1293        let mut generic_params = lifetimes
1294            .iter()
1295            .map(|lt| GenericParam {
1296                id: lt.id,
1297                ident: lt.ident,
1298                attrs: ast::AttrVec::new(),
1299                bounds: Vec::new(),
1300                is_placeholder: false,
1301                kind: ast::GenericParamKind::Lifetime,
1302                colon_span: None,
1303            })
1304            .collect::<ThinVec<GenericParam>>();
1305        lifetime_defs.append(&mut generic_params);
1306
1307        let generic_args_span = generic_args.span();
1308        let snippet = format!(
1309            "for<{}> ",
1310            lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1311        );
1312        let before_fn_path = fn_path.span.shrink_to_lo();
1313        self.dcx()
1314            .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
1315            .with_multipart_suggestion(
1316                "consider using a higher-ranked trait bound instead",
1317                vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1318                Applicability::MaybeIncorrect,
1319            )
1320            .emit();
1321        Ok(())
1322    }
1323
1324    pub(super) fn check_lifetime(&mut self) -> bool {
1325        self.expected_token_types.insert(TokenType::Lifetime);
1326        self.token.is_lifetime()
1327    }
1328
1329    /// Parses a single lifetime `'a` or panics.
1330    pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1331        if let Some((ident, is_raw)) = self.token.lifetime() {
1332            if matches!(is_raw, IdentIsRaw::No)
1333                && ident.without_first_quote().is_reserved()
1334                && ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
1335            {
1336                self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
1337            }
1338
1339            self.bump();
1340            Lifetime { ident, id: ast::DUMMY_NODE_ID }
1341        } else {
1342            self.dcx().span_bug(self.token.span, "not a lifetime")
1343        }
1344    }
1345
1346    pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
1347        P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1348    }
1349}