Skip to main content

rustc_parse/parser/
ty.rs

1use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind};
2use rustc_ast::util::case::Case;
3use rustc_ast::{
4    self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy,
5    GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
6    Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
7    TyKind, UnsafeBinderTy,
8};
9use rustc_errors::{Applicability, Diag, E0516, PResult};
10use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
11use thin_vec::{ThinVec, thin_vec};
12
13use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
14use crate::diagnostics::{
15    self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
16    FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidCVariadicType,
17    InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
18    ReturnTypesUseThinArrow,
19};
20use crate::parser::{FnContext, FnParseMode, FrontMatterParsingMode};
21use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
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(#[automatically_derived]
impl ::core::marker::Copy for AllowPlus { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for AllowPlus { }
#[automatically_derived]
impl ::core::clone::Clone for AllowPlus {
    #[inline]
    fn clone(&self) -> AllowPlus { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for AllowPlus { }
#[automatically_derived]
impl ::core::cmp::PartialEq for AllowPlus {
    #[inline]
    fn eq(&self, other: &AllowPlus) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
29pub(super) enum AllowPlus {
30    Yes,
31    No,
32}
33
34#[derive(#[automatically_derived]
impl ::core::marker::StructuralPartialEq for RecoverQPath { }
#[automatically_derived]
impl ::core::cmp::PartialEq for RecoverQPath {
    #[inline]
    fn eq(&self, other: &RecoverQPath) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}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(#[automatically_derived]
impl ::core::marker::Copy for RecoverReturnSign { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for RecoverReturnSign { }
#[automatically_derived]
impl ::core::clone::Clone for RecoverReturnSign {
    #[inline]
    fn clone(&self) -> RecoverReturnSign { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for RecoverReturnSign { }
#[automatically_derived]
impl ::core::cmp::PartialEq for RecoverReturnSign {
    #[inline]
    fn eq(&self, other: &RecoverReturnSign) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}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 => #[allow(non_exhaustive_omitted_patterns)] match token {
    token::FatArrow | token::Colon => true,
    _ => false,
}matches!(token, token::FatArrow | token::Colon),
70            Self::OnlyFatArrow => #[allow(non_exhaustive_omitted_patterns)] match token {
    token::FatArrow => true,
    _ => false,
}matches!(token, token::FatArrow),
71            Self::No => false,
72        }
73    }
74}
75
76// Is `...` (`CVarArgs`) legal at this level of type parsing?
77#[derive(#[automatically_derived]
impl ::core::marker::StructuralPartialEq for AllowCVariadic { }
#[automatically_derived]
impl ::core::cmp::PartialEq for AllowCVariadic {
    #[inline]
    fn eq(&self, other: &AllowCVariadic) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
78enum AllowCVariadic {
79    Yes,
80    No,
81}
82
83/// Determine if the given token can begin a bound assuming it follows Rust 2015 identifier `dyn`.
84///
85/// In Rust 2015, `dyn` is a contextual keyword, not a full one.
86fn can_begin_dyn_bound_in_edition_2015(t: Token) -> bool {
87    if t.is_path_start() {
88        // In `dyn::x`, `dyn<X>` and `dyn<<X>::Y>`, `dyn` should (continue to) denote a regular path
89        // segment for backward compatibility. We make an exception for `dyn(X)` which used to be
90        // interpreted as a path with parenthesized generic arguments which can be semantically
91        // well-formed (consider: `use std::ops::Fn as dyn;`). Instead, we treat it as a trait
92        // object type whose first bound is parenthesized.
93        return t != token::PathSep && t != token::Lt && t != token::Shl;
94    }
95
96    // Contrary to `Parser::can_begin_bound`, `!`, `const`, `[` and `async` are deliberately not
97    // part of this list to contain the number of potential regressions esp. in MBE code.
98    // `const` and `[` would regress UI test `macro-dyn-const-2015.rs` and
99    // `!` would regress `dyn!(...)` macro calls in Rust 2015 for example.
100    t == token::OpenParen || t == token::Question || t.is_lifetime() || t.is_keyword(kw::For)
101}
102
103impl<'a> Parser<'a> {
104    /// Parses a type.
105    pub fn parse_ty(&mut self) -> PResult<'a, Box<Ty>> {
106        if self.token == token::DotDotDot {
107            // We special case this so that we don't talk about "nested C-variadics" in types.
108            // We still pass in `AllowCVariadic::No` so that `parse_ty_common` can complain about
109            // things like `Vec<...>`.
110            let span = self.token.span;
111            self.bump();
112            let kind = TyKind::Err(self.dcx().emit_err(InvalidCVariadicType { span }));
113            return Ok(self.mk_ty(span, kind));
114        }
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
125    pub(super) fn parse_ty_with_generics_recovery(
126        &mut self,
127        ty_params: &Generics,
128    ) -> PResult<'a, Box<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.
142    pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, Box<Ty>> {
143        let ty = self.parse_ty_common(
144            AllowPlus::Yes,
145            AllowCVariadic::Yes,
146            RecoverQPath::Yes,
147            RecoverReturnSign::Yes,
148            None,
149            RecoverQuestionMark::Yes,
150        )?;
151
152        // Recover a trailing `= EXPR` if present.
153        if self.may_recover()
154            && self.check_noexpect(&token::Eq)
155            && self.look_ahead(1, |tok| tok.can_begin_expr())
156        {
157            let snapshot = self.create_snapshot_for_diagnostic();
158            self.bump();
159            let eq_span = self.prev_token.span;
160            match self.parse_expr() {
161                Ok(e) => {
162                    self.dcx()
163                        .struct_span_err(eq_span.to(e.span), "parameter defaults are not supported")
164                        .emit();
165                }
166                Err(diag) => {
167                    diag.cancel();
168                    self.restore_snapshot(snapshot);
169                }
170            }
171        }
172
173        Ok(ty)
174    }
175
176    /// Parses a type in restricted contexts where `+` is not permitted.
177    ///
178    /// Example 1: `&'a TYPE`
179    ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
180    /// Example 2: `value1 as TYPE + value2`
181    ///     `+` is prohibited to avoid interactions with expression grammar.
182    pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, Box<Ty>> {
183        self.parse_ty_common(
184            AllowPlus::No,
185            AllowCVariadic::No,
186            RecoverQPath::Yes,
187            RecoverReturnSign::Yes,
188            None,
189            RecoverQuestionMark::Yes,
190        )
191    }
192
193    /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
194    /// for better diagnostics involving `?`.
195    pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, Box<Ty>> {
196        self.parse_ty_common(
197            AllowPlus::No,
198            AllowCVariadic::No,
199            RecoverQPath::Yes,
200            RecoverReturnSign::Yes,
201            None,
202            RecoverQuestionMark::No,
203        )
204    }
205
206    pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, Box<Ty>> {
207        self.parse_ty_common(
208            AllowPlus::Yes,
209            AllowCVariadic::No,
210            RecoverQPath::Yes,
211            RecoverReturnSign::Yes,
212            None,
213            RecoverQuestionMark::No,
214        )
215    }
216
217    /// Parse a type without recovering `:` as `->` to avoid breaking code such
218    /// as `where fn() : for<'a>`.
219    pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, Box<Ty>> {
220        self.parse_ty_common(
221            AllowPlus::Yes,
222            AllowCVariadic::No,
223            RecoverQPath::Yes,
224            RecoverReturnSign::OnlyFatArrow,
225            None,
226            RecoverQuestionMark::Yes,
227        )
228    }
229
230    /// Parses an optional return type `[ -> TY ]` in a function declaration.
231    pub(super) fn parse_ret_ty(
232        &mut self,
233        allow_plus: AllowPlus,
234        recover_qpath: RecoverQPath,
235        recover_return_sign: RecoverReturnSign,
236    ) -> PResult<'a, FnRetTy> {
237        let lo = self.prev_token.span;
238        Ok(if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::RArrow,
    token_type: crate::parser::token_type::TokenType::RArrow,
}exp!(RArrow)) {
239            // FIXME(Centril): Can we unconditionally `allow_plus`?
240            let ty = self.parse_ty_common(
241                allow_plus,
242                AllowCVariadic::No,
243                recover_qpath,
244                recover_return_sign,
245                None,
246                RecoverQuestionMark::Yes,
247            )?;
248            FnRetTy::Ty(ty)
249        } else if recover_return_sign.can_recover(&self.token.kind) {
250            // Don't `eat` to prevent `=>` from being added as an expected token which isn't
251            // actually expected and could only confuse users
252            self.bump();
253            self.dcx().emit_err(ReturnTypesUseThinArrow {
254                span: self.prev_token.span,
255                suggestion: lo.between(self.token.span),
256            });
257            let ty = self.parse_ty_common(
258                allow_plus,
259                AllowCVariadic::No,
260                recover_qpath,
261                recover_return_sign,
262                None,
263                RecoverQuestionMark::Yes,
264            )?;
265            FnRetTy::Ty(ty)
266        } else {
267            FnRetTy::Default(self.prev_token.span.shrink_to_hi())
268        })
269    }
270
271    fn parse_ty_common(
272        &mut self,
273        allow_plus: AllowPlus,
274        allow_c_variadic: AllowCVariadic,
275        recover_qpath: RecoverQPath,
276        recover_return_sign: RecoverReturnSign,
277        ty_generics: Option<&Generics>,
278        recover_question_mark: RecoverQuestionMark,
279    ) -> PResult<'a, Box<Ty>> {
280        let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
281        if allow_qpath_recovery && self.may_recover() &&
                let Some(mv_kind) = self.token.is_metavar_seq() &&
            let token::MetaVarKind::Ty { .. } = mv_kind &&
        self.check_noexpect_past_close_delim(&token::PathSep) {
    let ty =
        self.eat_metavar_seq(mv_kind,
                |this|
                    this.parse_ty_no_question_mark_recover()).expect("metavar seq ty");
    return self.maybe_recover_from_bad_qpath_stage_2(self.prev_token.span,
            ty);
};maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
282
283        if let Some(ty) = self.eat_metavar_seq_with_matcher(
284            |mv_kind| #[allow(non_exhaustive_omitted_patterns)] match mv_kind {
    MetaVarKind::Ty { .. } => true,
    _ => false,
}matches!(mv_kind, MetaVarKind::Ty { .. }),
285            |this| this.parse_ty_no_question_mark_recover(),
286        ) {
287            return Ok(ty);
288        }
289
290        self.recover_from_outer_attributes("types")?;
291
292        let lo = self.token.span;
293        let mut impl_dyn_multi = false;
294        let kind = if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
295            self.parse_paren_start_ty(lo, allow_plus)?
296        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
297            // Never type `!`
298            TyKind::Never
299        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star)) {
300            self.parse_ty_ptr()?
301        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBracket,
    token_type: crate::parser::token_type::TokenType::OpenBracket,
}exp!(OpenBracket)) {
302            self.parse_array_or_slice_ty()?
303        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::And,
    token_type: crate::parser::token_type::TokenType::And,
}exp!(And)) || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::AndAnd,
    token_type: crate::parser::token_type::TokenType::AndAnd,
}exp!(AndAnd)) {
304            // Reference
305            self.expect_and()?;
306            self.parse_borrowed_pointee()?
307        } else if self.eat_keyword_noexpect(kw::Typeof) {
308            self.parse_typeof_ty(lo)?
309        } else if self.is_builtin() {
310            self.parse_builtin_ty()?
311        } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Underscore,
    token_type: crate::parser::token_type::TokenType::KwUnderscore,
}exp!(Underscore)) {
312            // A type to be inferred `_`
313            TyKind::Infer
314        } else if self.check_fn_front_matter(false, Case::Sensitive) {
315            // Function pointer type
316            self.parse_ty_fn_ptr(lo, ThinVec::new(), None, recover_return_sign)?
317        } else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::For,
    token_type: crate::parser::token_type::TokenType::KwFor,
}exp!(For)) {
318            // Function pointer type or bound list (trait object type) starting with a poly-trait.
319            //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
320            //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
321            let (bound_vars, _) = self.parse_higher_ranked_binder()?;
322            if self.check_fn_front_matter(false, Case::Sensitive) {
323                self.parse_ty_fn_ptr(
324                    lo,
325                    bound_vars,
326                    Some(self.prev_token.span.shrink_to_lo()),
327                    recover_return_sign,
328                )?
329            } else {
330                // Try to recover `for<'a> dyn Trait` or `for<'a> impl Trait`.
331                if self.may_recover()
332                    && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn))
333                {
334                    let kw = self.prev_token.ident().unwrap().0;
335                    let removal_span = kw.span.with_hi(self.token.span.lo());
336                    let path = self.parse_path(PathStyle::Type)?;
337                    let mut bounds = {
    let len = [()].len();
    let mut vec = ::thin_vec::ThinVec::with_capacity(len);
    vec.push(GenericBound::Trait(PolyTraitRef::new(bound_vars, path,
                TraitBoundModifiers::NONE, lo.to(self.prev_token.span),
                ast::Parens::No)));
    vec
}thin_vec![GenericBound::Trait(PolyTraitRef::new(
338                        bound_vars,
339                        path,
340                        TraitBoundModifiers::NONE,
341                        lo.to(self.prev_token.span),
342                        ast::Parens::No,
343                    ))];
344                    if allow_plus == AllowPlus::Yes && self.check_plus() {
345                        self.eat_plus();
346                        bounds.append(&mut self.parse_generic_bounds()?);
347                    }
348                    self.dcx().emit_err(diagnostics::TransposeDynOrImpl {
349                        span: kw.span,
350                        kw: kw.name.as_str(),
351                        sugg: diagnostics::TransposeDynOrImplSugg {
352                            removal_span,
353                            insertion_span: lo.shrink_to_lo(),
354                            kw: kw.name.as_str(),
355                        },
356                    });
357                    match kw.name {
358                        kw::Dyn => TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn),
359                        kw::Impl => TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds),
360                        _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
361                    }
362                } else {
363                    let path = self.parse_path(PathStyle::Type)?;
364                    let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
365                    self.finish_parsing_bare_trait_object_ty(
366                        bound_vars,
367                        path,
368                        lo,
369                        parse_plus,
370                        ast::Parens::No,
371                    )?
372                }
373            }
374        } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Impl,
    token_type: crate::parser::token_type::TokenType::KwImpl,
}exp!(Impl)) {
375            self.parse_impl_ty(&mut impl_dyn_multi)?
376        } else if self.is_explicit_dyn_type() {
377            self.parse_dyn_ty(&mut impl_dyn_multi)?
378        } else if self.eat_lt() {
379            // Qualified path
380            let (qself, path) = self.parse_qpath(PathStyle::Type)?;
381            TyKind::Path(Some(qself), path)
382        } else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
383            && self.look_ahead(1, |t| *t == token::Star)
384        {
385            self.parse_ty_c_style_pointer()?
386        } else if self.check_path() {
387            self.parse_path_start_ty(lo, allow_plus, ty_generics)?
388        } else if self.can_begin_bound() {
389            self.parse_bare_trait_object_ty(lo, allow_plus)?
390        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::DotDotDot,
    token_type: crate::parser::token_type::TokenType::DotDotDot,
}exp!(DotDotDot)) {
391            match allow_c_variadic {
392                AllowCVariadic::Yes => TyKind::CVarArgs,
393                AllowCVariadic::No => {
394                    // FIXME(c_variadic): Should we just allow `...` syntactically
395                    // anywhere in a type and use semantic restrictions instead?
396                    // NOTE: This may regress certain MBE calls if done incorrectly.
397                    let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
398                    TyKind::Err(guar)
399                }
400            }
401        } else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe))
402            && self.look_ahead(1, |tok| tok.kind == token::Lt)
403        {
404            self.parse_unsafe_binder_ty()?
405        } else {
406            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected type, found {0}",
                super::token_descr(&self.token)))
    })format!("expected type, found {}", super::token_descr(&self.token));
407            let mut err = self.dcx().struct_span_err(lo, msg);
408            err.span_label(lo, "expected type");
409            return Err(err);
410        };
411
412        let span = lo.to(self.prev_token.span);
413        let mut ty = self.mk_ty(span, kind);
414
415        // Try to recover from use of `+` with incorrect priority.
416        match allow_plus {
417            AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
418            AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
419        }
420        if let RecoverQuestionMark::Yes = recover_question_mark {
421            ty = self.maybe_recover_from_question_mark(ty);
422        }
423        if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
424    }
425
426    fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
427        let lo = self.token.span;
428        if !self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
                kw: rustc_span::symbol::kw::Unsafe,
                token_type: crate::parser::token_type::TokenType::KwUnsafe,
            }) {
    ::core::panicking::panic("assertion failed: self.eat_keyword(exp!(Unsafe))")
};assert!(self.eat_keyword(exp!(Unsafe)));
429        self.expect_lt()?;
430        let generic_params = self.parse_generic_params()?;
431        self.expect_gt()?;
432        let inner_ty = self.parse_ty()?;
433        let span = lo.to(self.prev_token.span);
434        self.psess.gated_spans.gate(sym::unsafe_binders, span);
435
436        Ok(TyKind::UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, inner_ty })))
437    }
438
439    /// Parse a type that begins with an opening parenthesis `(`.
440    ///
441    /// More specifically, it parses one of the following:
442    ///
443    /// 1. parenthesized type
444    /// 2. tuple type
445    /// 3. bare trait object type where the first trait bound is parenthesized
446    fn parse_paren_start_ty(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
447        let mut trailing_plus = false;
448        let (ts, trailing) = self.parse_paren_comma_seq(|p| {
449            let ty = p.parse_ty()?;
450            trailing_plus = p.prev_token == TokenKind::Plus;
451            Ok(ty)
452        })?;
453
454        if ts.len() == 1 && #[allow(non_exhaustive_omitted_patterns)] match trailing {
    Trailing::No => true,
    _ => false,
}matches!(trailing, Trailing::No) {
455            let ty = ts.into_iter().next().unwrap();
456
457            // Let's check if we actually have a bare trait object type where the first trait bound
458            // is parenthesized. That's the case if the parentheses are followed by a `+` and if
459            // what's contained between the parentheses resembles a *BareTraitBound*.
460            //
461            // For context, looking at bounds in general (see *Bound*), only trait bounds are
462            // allowed to be wrapped in parentheses, not however lifetime and use bounds.
463            let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
464            match ty.kind {
465                // `"(" TypePath ")" "+"`
466                TyKind::Path(None, path) if maybe_bounds => self
467                    .finish_parsing_bare_trait_object_ty(
468                        ThinVec::new(),
469                        path,
470                        lo,
471                        true,
472                        ast::Parens::Yes,
473                    ),
474                // `"(" BareTraitBound\TypePath | UseBound ")" "+"`
475                //
476                // * FIXME: As alluded to above, only trait bounds are meant to allow parens.
477                //   Arguably, it's an accident that we're permitting *UseBound*s and thus types
478                //   like `(use<>)+`. Might need a T-lang FCP to change this.
479                // * We're checking `!trailing_plus` to prevent us from accepting code like
480                //   `(T+)+` or `('a+)+`.
481                // * While we could be looking at `('a)+` which we don't want to accept, we
482                //   know that the `parse_ty` above has already emitted an error since the
483                //   lifetime isn't immediately followed by a `+`.
484                TyKind::TraitObject(mut bounds, TraitObjectSyntax::None)
485                    if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
486                {
487                    self.eat_plus();
488                    bounds.append(&mut self.parse_generic_bounds()?);
489                    Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
490                }
491                _ => Ok(TyKind::Paren(ty)),
492            }
493        } else {
494            Ok(TyKind::Tup(ts))
495        }
496    }
497
498    fn parse_bare_trait_object_ty(
499        &mut self,
500        lo: Span,
501        allow_plus: AllowPlus,
502    ) -> PResult<'a, TyKind> {
503        // A lifetime only begins a bare trait object type if it is followed by `+`!
504        if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) {
505            // In Rust 2021 and beyond, we assume that the user didn't intend to write a bare trait
506            // object type with a leading lifetime bound since that seems very unlikely given the
507            // fact that `dyn`-less trait objects are *semantically* invalid.
508            if self.psess.edition.at_least_rust_2021() {
509                let lt = self.expect_lifetime();
510                let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime");
511                err.span_label(lo, "expected type");
512                return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) {
513                    Ok(ref_ty) => ref_ty,
514                    Err(err) => TyKind::Err(err.emit()),
515                });
516            }
517
518            self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime {
519                span: lo,
520                suggestion: lo.shrink_to_hi(),
521            });
522        }
523        Ok(TyKind::TraitObject(
524            self.parse_generic_bounds_common(allow_plus)?,
525            TraitObjectSyntax::None,
526        ))
527    }
528
529    fn maybe_recover_ref_ty_no_leading_ampersand<'cx>(
530        &mut self,
531        lt: Lifetime,
532        lo: Span,
533        mut err: Diag<'cx>,
534    ) -> Result<TyKind, Diag<'cx>> {
535        if !self.may_recover() {
536            return Err(err);
537        }
538        let snapshot = self.create_snapshot_for_diagnostic();
539        let mutbl = self.parse_mutability();
540        match self.parse_ty_no_plus() {
541            Ok(ty) => {
542                err.span_suggestion_verbose(
543                    lo.shrink_to_lo(),
544                    "you might have meant to write a reference type here",
545                    "&",
546                    Applicability::MaybeIncorrect,
547                );
548                err.emit();
549                Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl }))
550            }
551            Err(diag) => {
552                diag.cancel();
553                self.restore_snapshot(snapshot);
554                Err(err)
555            }
556        }
557    }
558
559    fn finish_parsing_bare_trait_object_ty(
560        &mut self,
561        generic_params: ThinVec<GenericParam>,
562        path: ast::Path,
563        lo: Span,
564        parse_plus: bool,
565        parens: ast::Parens,
566    ) -> PResult<'a, TyKind> {
567        let mut bounds = {
    let len = [()].len();
    let mut vec = ::thin_vec::ThinVec::with_capacity(len);
    vec.push(GenericBound::Trait(PolyTraitRef::new(generic_params, path,
                TraitBoundModifiers::NONE, lo.to(self.prev_token.span),
                parens)));
    vec
}thin_vec![GenericBound::Trait(PolyTraitRef::new(
568            generic_params,
569            path,
570            TraitBoundModifiers::NONE,
571            lo.to(self.prev_token.span),
572            parens,
573        ))];
574        if parse_plus {
575            self.eat_plus();
576            bounds.append(&mut self.parse_generic_bounds()?);
577        }
578        Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
579    }
580
581    /// Parses a raw pointer with a C-style typo
582    fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> {
583        let kw_span = self.token.span;
584        let mutbl = self.parse_mut_or_const();
585
586        if let Some(mutbl) = mutbl
587            && self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star))
588        {
589            let star_span = self.prev_token.span;
590
591            let mutability = match mutbl {
592                Mutability::Not => "const",
593                Mutability::Mut => "mut",
594            };
595
596            let ty = self.parse_ty_no_question_mark_recover()?;
597
598            self.dcx()
599                .struct_span_err(
600                    kw_span,
601                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("raw pointer types must be written as `*{0} T`",
                mutability))
    })format!("raw pointer types must be written as `*{mutability} T`"),
602                )
603                .with_multipart_suggestion(
604                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("put the `*` before `{0}`",
                mutability))
    })format!("put the `*` before `{mutability}`"),
605                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(star_span, String::new()),
                (kw_span.shrink_to_lo(), "*".to_string())]))vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
606                    Applicability::MachineApplicable,
607                )
608                .emit();
609
610            return Ok(TyKind::Ptr(MutTy { ty, mutbl }));
611        }
612        // This is unreachable because we always get into if above and return from it
613        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("this could never happen")));
}unreachable!("this could never happen")
614    }
615
616    /// Parses a raw pointer type: `*[const | mut] $type`.
617    fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
618        let mutbl = self.parse_mut_or_const().unwrap_or_else(|| {
619            let span = self.prev_token.span;
620            self.dcx().emit_err(ExpectedMutOrConstInRawPointerType {
621                span,
622                after_asterisk: span.shrink_to_hi(),
623            });
624            Mutability::Not
625        });
626        let ty = self.parse_ty_no_plus()?;
627        Ok(TyKind::Ptr(MutTy { ty, mutbl }))
628    }
629
630    /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
631    /// The opening `[` bracket is already eaten.
632    fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
633        let elt_ty = self.parse_ty()?;
634
635        let ty = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
636            let mut length = self.parse_expr_anon_const()?;
637
638            if let Err(e) = self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBracket,
    token_type: crate::parser::token_type::TokenType::CloseBracket,
}exp!(CloseBracket)) {
639                // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
640                self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
641                self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBracket,
    token_type: crate::parser::token_type::TokenType::CloseBracket,
}exp!(CloseBracket))?;
642            }
643            TyKind::Array(elt_ty, length)
644        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBracket,
    token_type: crate::parser::token_type::TokenType::CloseBracket,
}exp!(CloseBracket)) {
645            TyKind::Slice(elt_ty)
646        } else {
647            self.maybe_recover_array_ty_without_semi(elt_ty)?
648        };
649
650        Ok(ty)
651    }
652
653    /// Recover from malformed array type syntax.
654    ///
655    /// This method attempts to recover from cases like:
656    /// - `[u8, 5]` → suggests using `;`, return a Array type
657    /// - `[u8 5]` → suggests using `;`, return a Array type
658    /// Consider to add more cases in the future.
659    fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: Box<Ty>) -> PResult<'a, TyKind> {
660        let span = self.token.span;
661        let token_descr = super::token_descr(&self.token);
662        let mut err =
663            self.dcx().struct_span_err(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected `;` or `]`, found {0}",
                token_descr))
    })format!("expected `;` or `]`, found {}", token_descr));
664        err.span_label(span, "expected `;` or `]`");
665
666        // If we cannot recover, return the error immediately.
667        if !self.may_recover() {
668            return Err(err);
669        }
670
671        let snapshot = self.create_snapshot_for_diagnostic();
672
673        // Consume common erroneous separators.
674        let hi = self.prev_token.span.hi();
675        _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma)) || self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)) || self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star));
676        let suggestion_span = self.prev_token.span.with_lo(hi);
677
678        // FIXME(mgca): recovery is broken for `const {` args
679        // we first try to parse pattern like `[u8 5]`
680        let length = match self.parse_expr_anon_const() {
681            Ok(length) => length,
682            Err(e) => {
683                e.cancel();
684                self.restore_snapshot(snapshot);
685                return Err(err);
686            }
687        };
688
689        if let Err(e) = self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBracket,
    token_type: crate::parser::token_type::TokenType::CloseBracket,
}exp!(CloseBracket)) {
690            e.cancel();
691            self.restore_snapshot(snapshot);
692            return Err(err);
693        }
694
695        err.span_suggestion_verbose(
696            suggestion_span,
697            "you might have meant to use `;` as the separator",
698            ";",
699            Applicability::MaybeIncorrect,
700        );
701        err.emit();
702        Ok(TyKind::Array(elt_ty, length))
703    }
704
705    fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
706        let and_span = self.prev_token.span;
707        let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
708        let (pinned, mut mutbl) = self.parse_pin_and_mut();
709        if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
710            // A lifetime is invalid here: it would be part of a bare trait bound, which requires
711            // it to be followed by a plus, but we disallow plus in the pointee type.
712            // So we can handle this case as an error here, and suggest `'a mut`.
713            // If there *is* a plus next though, handling the error later provides better suggestions
714            // (like adding parentheses)
715            if !self.look_ahead(1, |t| t.is_like_plus()) {
716                let lifetime_span = self.token.span;
717                let span = and_span.to(lifetime_span);
718
719                let (suggest_lifetime, snippet) =
720                    if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
721                        (Some(span), lifetime_src)
722                    } else {
723                        (None, String::new())
724                    };
725                self.dcx().emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
726
727                opt_lifetime = Some(self.expect_lifetime());
728            }
729        } else if self.token.is_keyword(kw::Dyn)
730            && mutbl == Mutability::Not
731            && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
732        {
733            // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
734            let span = and_span.to(self.look_ahead(1, |t| t.span));
735            self.dcx().emit_err(DynAfterMut { span });
736
737            // Recovery
738            mutbl = Mutability::Mut;
739            let (dyn_tok, dyn_tok_sp) = (self.token, self.token_spacing);
740            self.bump();
741            self.bump_with((dyn_tok, dyn_tok_sp));
742        }
743        let ty = self.parse_ty_no_plus()?;
744        Ok(match pinned {
745            Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
746            Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
747        })
748    }
749
750    /// Parse nothing, mutability or `pin` followed by "explicit" mutability.
751    ///
752    /// ```ebnf
753    /// PinAndMut = "pin" MutOrConst | "mut"
754    /// ```
755    pub(crate) fn parse_pin_and_mut(&mut self) -> (Pinnedness, Mutability) {
756        if self.token.is_keyword(kw::Pin) && self.look_ahead(1, Token::is_mutability) {
757            self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
758            if !self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
                kw: rustc_span::symbol::kw::Pin,
                token_type: crate::parser::token_type::TokenType::KwMut,
            }) {
    ::core::panicking::panic("assertion failed: self.eat_keyword(exp!(Pin))")
};assert!(self.eat_keyword(exp!(Pin)));
759            let mutbl = self.parse_mut_or_const().unwrap();
760            (Pinnedness::Pinned, mutbl)
761        } else {
762            (Pinnedness::Not, self.parse_mutability())
763        }
764    }
765
766    /// Parses the `typeof(EXPR)` for better diagnostics before returning
767    /// an error type.
768    fn parse_typeof_ty(&mut self, lo: Span) -> PResult<'a, TyKind> {
769        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen))?;
770        let _expr = self.parse_expr_anon_const()?;
771        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen))?;
772        let span = lo.to(self.prev_token.span);
773        let guar = self
774            .dcx()
775            .struct_span_err(span, "`typeof` is a reserved keyword but unimplemented")
776            .with_note("consider replacing `typeof(...)` with an actual type")
777            .with_code(E0516)
778            .emit();
779        Ok(TyKind::Err(guar))
780    }
781
782    fn parse_builtin_ty(&mut self) -> PResult<'a, TyKind> {
783        self.parse_builtin(|this, lo, ident| {
784            Ok(match ident.name {
785                sym::field_of => Some(this.parse_ty_field_of(lo)?),
786                _ => None,
787            })
788        })
789    }
790
791    pub(crate) fn parse_ty_field_of(&mut self, _lo: Span) -> PResult<'a, TyKind> {
792        let container = self.parse_ty()?;
793        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma))?;
794
795        let fields = self.parse_floating_field_access()?;
796        let trailing_comma = self.eat_noexpect(&TokenKind::Comma);
797
798        if let Err(mut e) = self.expect_one_of(&[], &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)]) {
799            if trailing_comma {
800                e.note("unexpected third argument to field_of");
801            } else {
802                e.note("field_of expects dot-separated field and variant names");
803            }
804            e.emit();
805        }
806
807        // Eat tokens until the macro call ends.
808        if self.may_recover() {
809            while !self.token.kind.is_close_delim_or_eof() {
810                self.bump();
811            }
812        }
813
814        match *fields {
815            [] => Err(self.dcx().struct_span_err(
816                self.token.span,
817                "`field_of!` expects dot-separated field and variant names",
818            )),
819            [field] => Ok(TyKind::FieldOf(container, None, field)),
820            [variant, field] => Ok(TyKind::FieldOf(container, Some(variant), field)),
821            _ => Err(self.dcx().struct_span_err(
822                fields.iter().map(|f| f.span).collect::<Vec<_>>(),
823                "`field_of!` only supports a single field or a variant with a field",
824            )),
825        }
826    }
827
828    /// Parses a function pointer type (`TyKind::FnPtr`).
829    /// ```ignore (illustrative)
830    ///    [unsafe] [extern "ABI"] fn (S) -> T
831    /// //  ^~~~~^          ^~~~^     ^~^    ^
832    /// //    |               |        |     |
833    /// //    |               |        |   Return type
834    /// // Function Style    ABI  Parameter types
835    /// ```
836    /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
837    fn parse_ty_fn_ptr(
838        &mut self,
839        lo: Span,
840        mut params: ThinVec<GenericParam>,
841        param_insertion_point: Option<Span>,
842        recover_return_sign: RecoverReturnSign,
843    ) -> PResult<'a, TyKind> {
844        let inherited_vis = rustc_ast::Visibility {
845            span: rustc_span::DUMMY_SP,
846            kind: rustc_ast::VisibilityKind::Inherited,
847        };
848        let span_start = self.token.span;
849        let ast::FnHeader { ext, safety, .. } = self.parse_fn_front_matter(
850            &inherited_vis,
851            Case::Sensitive,
852            FrontMatterParsingMode::FunctionPtrType,
853        )?;
854        if self.may_recover() && self.token == TokenKind::Lt {
855            self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
856        }
857        let mode = crate::parser::FnParseMode {
858            req_name: |_, _| false,
859            context: FnContext::FunctionPtrType,
860            req_body: false,
861        };
862        let decl = self.parse_fn_decl(&mode, AllowPlus::No, recover_return_sign)?;
863
864        let decl_span = span_start.to(self.prev_token.span);
865        Ok(TyKind::FnPtr(Box::new(FnPtrTy {
866            ext,
867            safety,
868            generic_params: params,
869            decl,
870            decl_span,
871        })))
872    }
873
874    /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
875    fn recover_fn_ptr_with_generics(
876        &mut self,
877        lo: Span,
878        params: &mut ThinVec<GenericParam>,
879        param_insertion_point: Option<Span>,
880    ) -> PResult<'a, ()> {
881        let generics = self.parse_generics()?;
882        let arity = generics.params.len();
883
884        let mut lifetimes: ThinVec<_> = generics
885            .params
886            .into_iter()
887            .filter(|param| #[allow(non_exhaustive_omitted_patterns)] match param.kind {
    ast::GenericParamKind::Lifetime => true,
    _ => false,
}matches!(param.kind, ast::GenericParamKind::Lifetime))
888            .collect();
889
890        let sugg = if !lifetimes.is_empty() {
891            let snippet =
892                lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
893
894            let (left, snippet) = if let Some(span) = param_insertion_point {
895                (span, if params.is_empty() { snippet } else { ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(", {0}", snippet))
    })format!(", {snippet}") })
896            } else {
897                (lo.shrink_to_lo(), ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("for<{0}> ", snippet))
    })format!("for<{snippet}> "))
898            };
899
900            Some(FnPtrWithGenericsSugg {
901                left,
902                snippet,
903                right: generics.span,
904                arity,
905                for_param_list_exists: param_insertion_point.is_some(),
906            })
907        } else {
908            None
909        };
910
911        self.dcx().emit_err(FnPtrWithGenerics { span: generics.span, sugg });
912        params.append(&mut lifetimes);
913        Ok(())
914    }
915
916    /// Parses an `impl B0 + ... + Bn` type.
917    fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
918        if self.token.is_lifetime() {
919            self.look_ahead(1, |t| {
920                if let token::Ident(sym, _) = t.kind {
921                    // parse pattern with "'a Sized" we're supposed to give suggestion like
922                    // "'a + Sized"
923                    self.dcx().emit_err(diagnostics::MissingPlusBounds {
924                        span: self.token.span,
925                        hi: self.token.span.shrink_to_hi(),
926                        sym,
927                    });
928                }
929            })
930        }
931
932        // Always parse bounds greedily for better error recovery.
933        let bounds = self.parse_generic_bounds()?;
934
935        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
936
937        Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
938    }
939
940    /// Parse a use-bound aka precise capturing list.
941    ///
942    /// ```ebnf
943    /// UseBound = "use" "<" (PreciseCapture ("," PreciseCapture)* ","?)? ">"
944    /// PreciseCapture = "Self" | Ident | Lifetime
945    /// ```
946    fn parse_use_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
947        self.expect_lt()?;
948        let (args, _, _) = self.parse_seq_to_before_tokens(
949            &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Gt,
    token_type: crate::parser::token_type::TokenType::Gt,
}exp!(Gt)],
950            &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr],
951            SeqSep::trailing_allowed(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma)),
952            |self_| {
953                if self_.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::SelfUpper,
    token_type: crate::parser::token_type::TokenType::KwSelfUpper,
}exp!(SelfUpper)) {
954                    self_.bump();
955                    Ok(PreciseCapturingArg::Arg(
956                        ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
957                        DUMMY_NODE_ID,
958                    ))
959                } else if self_.check_ident() {
960                    Ok(PreciseCapturingArg::Arg(
961                        ast::Path::from_ident(self_.parse_ident()?),
962                        DUMMY_NODE_ID,
963                    ))
964                } else if self_.check_lifetime() {
965                    Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
966                } else {
967                    self_.unexpected_any()
968                }
969            },
970        )?;
971        self.expect_gt()?;
972
973        if let ast::Parens::Yes = parens {
974            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen))?;
975            self.report_parenthesized_bound(lo, self.prev_token.span, "precise capturing lists");
976        }
977
978        Ok(GenericBound::Use(args, lo.to(self.prev_token.span)))
979    }
980
981    /// Is a `dyn B0 + ... + Bn` type allowed here?
982    fn is_explicit_dyn_type(&mut self) -> bool {
983        self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Dyn,
    token_type: crate::parser::token_type::TokenType::KwDyn,
}exp!(Dyn))
984            && (self.token_uninterpolated_span().at_least_rust_2018()
985                || self.look_ahead(1, |&t| can_begin_dyn_bound_in_edition_2015(t)))
986    }
987
988    /// Parses a `dyn B0 + ... + Bn` type.
989    ///
990    /// Note that this does *not* parse bare trait objects.
991    fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
992        self.bump(); // `dyn`
993
994        // Always parse bounds greedily for better error recovery.
995        let bounds = self.parse_generic_bounds()?;
996        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
997
998        Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn))
999    }
1000
1001    /// Parse a type that begins with a path.
1002    ///
1003    /// This can be:
1004    /// 1. a type macro, `mac!(...)`,
1005    /// 2. a bare trait object type, `B0 + ... + Bn`,
1006    /// 3. or a path, `path::to::MyType`.
1007    fn parse_path_start_ty(
1008        &mut self,
1009        lo: Span,
1010        allow_plus: AllowPlus,
1011        ty_generics: Option<&Generics>,
1012    ) -> PResult<'a, TyKind> {
1013        // Simple path
1014        let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
1015        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
1016            // Macro invocation in type position
1017            Ok(TyKind::MacCall(Box::new(MacCall { path, args: self.parse_delim_args()? })))
1018        } else if allow_plus == AllowPlus::Yes && self.check_plus() {
1019            // `Trait1 + Trait2 + 'a`
1020            self.finish_parsing_bare_trait_object_ty(
1021                ThinVec::new(),
1022                path,
1023                lo,
1024                true,
1025                ast::Parens::No,
1026            )
1027        } else {
1028            // Just a type path.
1029            Ok(TyKind::Path(None, path))
1030        }
1031    }
1032
1033    pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
1034        self.parse_generic_bounds_common(AllowPlus::Yes)
1035    }
1036
1037    /// Parse generic bounds.
1038    ///
1039    /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
1040    /// Otherwise, this only parses a single bound or none.
1041    fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
1042        let mut bounds = ThinVec::new();
1043
1044        // In addition to looping while we find generic bounds:
1045        // We continue even if we find a keyword. This is necessary for error recovery on,
1046        // for example, `impl fn()`. The only keyword that can go after generic bounds is
1047        // `where`, so stop if it's it.
1048        // We also continue if we find types (not traits), again for error recovery.
1049        while self.can_begin_bound()
1050            || (self.may_recover()
1051                && (self.token.can_begin_type()
1052                    || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
1053        {
1054            if self.token.is_keyword(kw::Dyn) && self.token.span.edition().at_least_rust_2018() {
1055                // Account for `&dyn Trait + dyn Other`.
1056                self.bump();
1057                self.dcx().emit_err(InvalidDynKeyword {
1058                    span: self.prev_token.span,
1059                    suggestion: self.prev_token.span.until(self.token.span),
1060                });
1061            }
1062            bounds.push(self.parse_generic_bound()?);
1063            if allow_plus == AllowPlus::No || !self.eat_plus() {
1064                break;
1065            }
1066        }
1067
1068        Ok(bounds)
1069    }
1070
1071    /// Can the current token begin a bound?
1072    fn can_begin_bound(&mut self) -> bool {
1073        // NOTE: Tokens `!`, `~`, `const` & `async` which represent the start of currently unstable
1074        //       trait bound modifiers are intentionally not included in `Token::can_begin_type` to
1075        //       avoid affecting stable macro matching behavior.
1076
1077        self.check_path()
1078            || self.check_lifetime()
1079            || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))
1080            || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Question,
    token_type: crate::parser::token_type::TokenType::Question,
}exp!(Question))
1081            || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Tilde,
    token_type: crate::parser::token_type::TokenType::Tilde,
}exp!(Tilde))
1082            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::For,
    token_type: crate::parser::token_type::TokenType::KwFor,
}exp!(For))
1083            || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen))
1084            || self.can_begin_maybe_const_bound()
1085            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const))
1086            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async))
1087            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Use,
    token_type: crate::parser::token_type::TokenType::KwUse,
}exp!(Use))
1088    }
1089
1090    fn can_begin_maybe_const_bound(&mut self) -> bool {
1091        self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBracket,
    token_type: crate::parser::token_type::TokenType::OpenBracket,
}exp!(OpenBracket))
1092            && self.look_ahead(1, |t| t.is_keyword(kw::Const))
1093            && self.look_ahead(2, |t| *t == token::CloseBracket)
1094    }
1095
1096    /// Parse a bound.
1097    ///
1098    /// ```ebnf
1099    /// Bound = LifetimeBound | UseBound | TraitBound
1100    /// ```
1101    fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
1102        let leading_token = self.prev_token;
1103        let lo = self.token.span;
1104
1105        // We only admit parenthesized *trait* bounds. However, we want to gracefully recover from
1106        // other kinds of parenthesized bounds, so parse the opening parenthesis *here*.
1107        //
1108        // In the future we might want to lift this syntactic restriction and
1109        // introduce "`GenericBound::Paren(Box<GenericBound>)`".
1110        let parens = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) { ast::Parens::Yes } else { ast::Parens::No };
1111
1112        if self.token.is_lifetime() {
1113            self.parse_lifetime_bound(lo, parens)
1114        } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Use,
    token_type: crate::parser::token_type::TokenType::KwUse,
}exp!(Use)) {
1115            self.parse_use_bound(lo, parens)
1116        } else {
1117            self.parse_trait_bound(lo, parens, &leading_token)
1118        }
1119    }
1120
1121    /// Parse a lifetime-bound aka outlives-bound.
1122    ///
1123    /// ```ebnf
1124    /// LifetimeBound = Lifetime
1125    /// ```
1126    fn parse_lifetime_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
1127        let lt = self.expect_lifetime();
1128
1129        if let ast::Parens::Yes = parens {
1130            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen))?;
1131            self.report_parenthesized_bound(lo, self.prev_token.span, "lifetime bounds");
1132        }
1133
1134        Ok(GenericBound::Outlives(lt))
1135    }
1136
1137    fn report_parenthesized_bound(&self, lo: Span, hi: Span, kind: &str) -> ErrorGuaranteed {
1138        let mut diag =
1139            self.dcx().struct_span_err(lo.to(hi), ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} may not be parenthesized",
                kind))
    })format!("{kind} may not be parenthesized"));
1140        diag.multipart_suggestion(
1141            "remove the parentheses",
1142            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(lo, String::new()), (hi, String::new())]))vec![(lo, String::new()), (hi, String::new())],
1143            Applicability::MachineApplicable,
1144        );
1145        diag.emit()
1146    }
1147
1148    /// Emits an error if any trait bound modifiers were present.
1149    fn error_lt_bound_with_modifiers(
1150        &self,
1151        modifiers: TraitBoundModifiers,
1152        binder_span: Option<Span>,
1153    ) -> ErrorGuaranteed {
1154        let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
1155
1156        match constness {
1157            BoundConstness::Never => {}
1158            BoundConstness::Always(span) | BoundConstness::Maybe(span) => {
1159                return self.dcx().emit_err(diagnostics::ModifierLifetime {
1160                    span,
1161                    modifier: constness.as_str(),
1162                });
1163            }
1164        }
1165
1166        match polarity {
1167            BoundPolarity::Positive => {}
1168            BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
1169                return self
1170                    .dcx()
1171                    .emit_err(diagnostics::ModifierLifetime { span, modifier: polarity.as_str() });
1172            }
1173        }
1174
1175        match asyncness {
1176            BoundAsyncness::Normal => {}
1177            BoundAsyncness::Async(span) => {
1178                return self.dcx().emit_err(diagnostics::ModifierLifetime {
1179                    span,
1180                    modifier: asyncness.as_str(),
1181                });
1182            }
1183        }
1184
1185        if let Some(span) = binder_span {
1186            return self
1187                .dcx()
1188                .emit_err(diagnostics::ModifierLifetime { span, modifier: "for<...>" });
1189        }
1190
1191        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")));
}unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
1192    }
1193
1194    /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
1195    ///
1196    /// If no modifiers are present, this does not consume any tokens.
1197    ///
1198    /// ```ebnf
1199    /// Constness = ("const" | "[" "const" "]")?
1200    /// Asyncness = "async"?
1201    /// Polarity = ("?" | "!")?
1202    /// ```
1203    ///
1204    /// See `parse_trait_bound` for more context.
1205    fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
1206        let modifier_lo = self.token.span;
1207        let constness = self.parse_bound_constness()?;
1208
1209        let asyncness = if self.token_uninterpolated_span().at_least_rust_2018()
1210            && self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async))
1211        {
1212            self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1213            BoundAsyncness::Async(self.prev_token.span)
1214        } else if self.may_recover()
1215            && self.token_uninterpolated_span().is_rust_2015()
1216            && self.is_kw_followed_by_ident(kw::Async)
1217        {
1218            self.bump(); // eat `async`
1219            self.dcx().emit_err(diagnostics::AsyncBoundModifierIn2015 {
1220                span: self.prev_token.span,
1221                help: HelpUseLatestEdition::new(),
1222            });
1223            self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1224            BoundAsyncness::Async(self.prev_token.span)
1225        } else {
1226            BoundAsyncness::Normal
1227        };
1228        let modifier_hi = self.prev_token.span;
1229
1230        let polarity = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Question,
    token_type: crate::parser::token_type::TokenType::Question,
}exp!(Question)) {
1231            BoundPolarity::Maybe(self.prev_token.span)
1232        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
1233            self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
1234            BoundPolarity::Negative(self.prev_token.span)
1235        } else {
1236            BoundPolarity::Positive
1237        };
1238
1239        // Enforce the mutual-exclusivity of `const`/`async` and `?`/`!`.
1240        match polarity {
1241            BoundPolarity::Positive => {
1242                // All trait bound modifiers allowed to combine with positive polarity
1243            }
1244            BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1245                match (asyncness, constness) {
1246                    (BoundAsyncness::Normal, BoundConstness::Never) => {
1247                        // Ok, no modifiers.
1248                    }
1249                    (_, _) => {
1250                        let constness = constness.as_str();
1251                        let asyncness = asyncness.as_str();
1252                        let glue =
1253                            if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
1254                        let modifiers_concatenated = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}{2}", constness, glue,
                asyncness))
    })format!("{constness}{glue}{asyncness}");
1255                        self.dcx().emit_err(diagnostics::PolarityAndModifiers {
1256                            polarity_span,
1257                            polarity: polarity.as_str(),
1258                            modifiers_span: modifier_lo.to(modifier_hi),
1259                            modifiers_concatenated,
1260                        });
1261                    }
1262                }
1263            }
1264        }
1265
1266        Ok(TraitBoundModifiers { constness, asyncness, polarity })
1267    }
1268
1269    pub fn parse_bound_constness(&mut self) -> PResult<'a, BoundConstness> {
1270        // FIXME(const_trait_impl): remove `~const` parser support once bootstrap has the new syntax
1271        // in rustfmt
1272        Ok(if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Tilde,
    token_type: crate::parser::token_type::TokenType::Tilde,
}exp!(Tilde)) {
1273            let tilde = self.prev_token.span;
1274            self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const))?;
1275            let span = tilde.to(self.prev_token.span);
1276            self.psess.gated_spans.gate(sym::const_trait_impl, span);
1277            BoundConstness::Maybe(span)
1278        } else if self.can_begin_maybe_const_bound() {
1279            let start = self.token.span;
1280            self.bump();
1281            self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const)).unwrap();
1282            self.bump();
1283            let span = start.to(self.prev_token.span);
1284            self.psess.gated_spans.gate(sym::const_trait_impl, span);
1285            BoundConstness::Maybe(span)
1286        } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const)) {
1287            self.psess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span);
1288            BoundConstness::Always(self.prev_token.span)
1289        } else {
1290            BoundConstness::Never
1291        })
1292    }
1293
1294    /// Parse a trait bound.
1295    ///
1296    /// ```ebnf
1297    /// TraitBound = BareTraitBound | "(" BareTraitBound ")"
1298    /// BareTraitBound =
1299    ///     (HigherRankedBinder Constness Asyncness | Polarity)
1300    ///     TypePath
1301    /// ```
1302    fn parse_trait_bound(
1303        &mut self,
1304        lo: Span,
1305        parens: ast::Parens,
1306        leading_token: &Token,
1307    ) -> PResult<'a, GenericBound> {
1308        let (mut bound_vars, binder_span) = self.parse_higher_ranked_binder()?;
1309
1310        let modifiers_lo = self.token.span;
1311        let modifiers = self.parse_trait_bound_modifiers()?;
1312        let modifiers_span = modifiers_lo.to(self.prev_token.span);
1313
1314        if let Some(binder_span) = binder_span {
1315            match modifiers.polarity {
1316                BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1317                    self.dcx().emit_err(diagnostics::BinderAndPolarity {
1318                        binder_span,
1319                        polarity_span,
1320                        polarity: modifiers.polarity.as_str(),
1321                    });
1322                }
1323                BoundPolarity::Positive => {}
1324            }
1325        }
1326
1327        // Recover erroneous lifetime bound with modifiers or binder.
1328        // e.g. `T: for<'a> 'a` or `T: [const] 'a`.
1329        if self.token.is_lifetime() {
1330            let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
1331            return self.parse_lifetime_bound(lo, parens);
1332        }
1333
1334        if let (more_bound_vars, Some(binder_span)) = self.parse_higher_ranked_binder()? {
1335            bound_vars.extend(more_bound_vars);
1336            self.dcx().emit_err(diagnostics::BinderBeforeModifiers { binder_span, modifiers_span });
1337        }
1338
1339        let mut path = if self.token.is_keyword(kw::Fn)
1340            && self.look_ahead(1, |t| *t == TokenKind::OpenParen)
1341            && let Some(path) = self.recover_path_from_fn()
1342        {
1343            path
1344        } else if !self.token.is_path_start() && self.token.can_begin_type() {
1345            let ty = self.parse_ty_no_plus()?;
1346            // Instead of finding a path (a trait), we found a type.
1347            let mut err = self.dcx().struct_span_err(ty.span, "expected a trait, found type");
1348
1349            // If we can recover, try to extract a path from the type. Note
1350            // that we do not use the try operator when parsing the type because
1351            // if it fails then we get a parser error which we don't want (we're trying
1352            // to recover from errors, not make more).
1353            let path = if self.may_recover() {
1354                let (span, message, sugg, path, applicability) = match &ty.kind {
1355                    TyKind::Ptr(..) | TyKind::Ref(..)
1356                        if let TyKind::Path(_, path) = &ty.peel_refs().kind =>
1357                    {
1358                        (
1359                            ty.span.until(path.span),
1360                            "consider removing the indirection",
1361                            "",
1362                            path,
1363                            Applicability::MaybeIncorrect,
1364                        )
1365                    }
1366                    TyKind::ImplTrait(_, bounds)
1367                        if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
1368                    {
1369                        (
1370                            ty.span.until(tr.span),
1371                            "use the trait bounds directly",
1372                            "",
1373                            &tr.trait_ref.path,
1374                            Applicability::MachineApplicable,
1375                        )
1376                    }
1377                    _ => return Err(err),
1378                };
1379
1380                err.span_suggestion_verbose(span, message, sugg, applicability);
1381
1382                path.clone()
1383            } else {
1384                return Err(err);
1385            };
1386
1387            err.emit();
1388
1389            path
1390        } else {
1391            self.parse_path(PathStyle::Type)?
1392        };
1393
1394        if self.may_recover() && self.token == TokenKind::OpenParen {
1395            self.recover_fn_trait_with_lifetime_params(&mut path, &mut bound_vars)?;
1396        }
1397
1398        if let ast::Parens::Yes = parens {
1399            // Someone has written something like `&dyn (Trait + Other)`. The correct code
1400            // would be `&(dyn Trait + Other)`
1401            if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1402                self.eat_plus();
1403                self.parse_generic_bounds()?;
1404                self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen))?;
1405
1406                self.dcx().emit_err(diagnostics::IncorrectParensTraitBounds {
1407                    span: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [lo, self.prev_token.span]))vec![lo, self.prev_token.span],
1408                    sugg: diagnostics::IncorrectParensTraitBoundsSugg {
1409                        wrong_span: leading_token.span.shrink_to_hi().to(lo),
1410                        new_span: leading_token.span.shrink_to_lo(),
1411                    },
1412                });
1413            } else {
1414                self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen))?;
1415            }
1416        }
1417
1418        let poly_trait =
1419            PolyTraitRef::new(bound_vars, path, modifiers, lo.to(self.prev_token.span), parens);
1420        Ok(GenericBound::Trait(poly_trait))
1421    }
1422
1423    // recovers a `Fn(..)` parenthesized-style path from `fn(..)`
1424    fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1425        let fn_token_span = self.token.span;
1426        self.bump();
1427        let args_lo = self.token.span;
1428        let snapshot = self.create_snapshot_for_diagnostic();
1429        let mode =
1430            FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
1431        match self.parse_fn_decl(&mode, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1432            Ok(decl) => {
1433                self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1434                Some(ast::Path {
1435                    span: fn_token_span.to(self.prev_token.span),
1436                    segments: {
    let len = [()].len();
    let mut vec = ::thin_vec::ThinVec::with_capacity(len);
    vec.push(ast::PathSegment {
            ident: Ident::new(sym::Fn, fn_token_span),
            id: DUMMY_NODE_ID,
            args: Some(Box::new(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
                            span: args_lo.to(self.prev_token.span),
                            inputs: decl.inputs.iter().map(|a| a.clone()).collect(),
                            inputs_span: args_lo.until(decl.output.span()),
                            output: decl.output.clone(),
                        }))),
        });
    vec
}thin_vec![ast::PathSegment {
1437                        ident: Ident::new(sym::Fn, fn_token_span),
1438                        id: DUMMY_NODE_ID,
1439                        args: Some(Box::new(ast::GenericArgs::Parenthesized(
1440                            ast::ParenthesizedArgs {
1441                                span: args_lo.to(self.prev_token.span),
1442                                inputs: decl.inputs.iter().map(|a| a.clone()).collect(),
1443                                inputs_span: args_lo.until(decl.output.span()),
1444                                output: decl.output.clone(),
1445                            }
1446                        ))),
1447                    }],
1448                })
1449            }
1450            Err(diag) => {
1451                diag.cancel();
1452                self.restore_snapshot(snapshot);
1453                None
1454            }
1455        }
1456    }
1457
1458    /// Parse an optional higher-ranked binder.
1459    ///
1460    /// ```ebnf
1461    /// HigherRankedBinder = ("for" "<" GenericParams ">")?
1462    /// ```
1463    pub(super) fn parse_higher_ranked_binder(
1464        &mut self,
1465    ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
1466        if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::For,
    token_type: crate::parser::token_type::TokenType::KwFor,
}exp!(For)) {
1467            let lo = self.token.span;
1468            self.expect_lt()?;
1469            let params = self.parse_generic_params()?;
1470            self.expect_gt()?;
1471            // We rely on AST validation to rule out invalid cases: There must not be
1472            // type or const parameters, and parameters must not have bounds.
1473            Ok((params, Some(lo.to(self.prev_token.span))))
1474        } else {
1475            Ok((ThinVec::new(), None))
1476        }
1477    }
1478
1479    /// Recover from `Fn`-family traits (Fn, FnMut, FnOnce) with lifetime arguments
1480    /// (e.g. `FnOnce<'a>(&'a str) -> bool`). Up to generic arguments have already
1481    /// been eaten.
1482    fn recover_fn_trait_with_lifetime_params(
1483        &mut self,
1484        fn_path: &mut ast::Path,
1485        lifetime_defs: &mut ThinVec<GenericParam>,
1486    ) -> PResult<'a, ()> {
1487        let fn_path_segment = fn_path.segments.last_mut().unwrap();
1488        let generic_args = if let Some(p_args) = &fn_path_segment.args {
1489            *p_args.clone()
1490        } else {
1491            // Normally it wouldn't come here because the upstream should have parsed
1492            // generic parameters (otherwise it's impossible to call this function).
1493            return Ok(());
1494        };
1495        let lifetimes =
1496            if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1497                &generic_args
1498            {
1499                args.into_iter()
1500                    .filter_map(|arg| {
1501                        if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1502                            && let ast::GenericArg::Lifetime(lifetime) = generic_arg
1503                        {
1504                            Some(lifetime)
1505                        } else {
1506                            None
1507                        }
1508                    })
1509                    .collect()
1510            } else {
1511                Vec::new()
1512            };
1513        // Only try to recover if the trait has lifetime params.
1514        if lifetimes.is_empty() {
1515            return Ok(());
1516        }
1517
1518        let snapshot = if self.parsing_generics {
1519            // The snapshot is only relevant if we're parsing the generics of an `fn` to avoid
1520            // incorrect recovery.
1521            Some(self.create_snapshot_for_diagnostic())
1522        } else {
1523            None
1524        };
1525        // Parse `(T, U) -> R`.
1526        let inputs_lo = self.token.span;
1527        let mode =
1528            FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
1529        let inputs = match self.parse_fn_params(&mode) {
1530            Ok(params) => params,
1531            Err(err) => {
1532                if let Some(snapshot) = snapshot {
1533                    self.restore_snapshot(snapshot);
1534                    err.cancel();
1535                    return Ok(());
1536                } else {
1537                    return Err(err);
1538                }
1539            }
1540        };
1541        let inputs_span = inputs_lo.to(self.prev_token.span);
1542        let output = match self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)
1543        {
1544            Ok(output) => output,
1545            Err(err) => {
1546                if let Some(snapshot) = snapshot {
1547                    self.restore_snapshot(snapshot);
1548                    err.cancel();
1549                    return Ok(());
1550                } else {
1551                    return Err(err);
1552                }
1553            }
1554        };
1555        let args = ast::ParenthesizedArgs {
1556            span: fn_path_segment.span().to(self.prev_token.span),
1557            inputs,
1558            inputs_span,
1559            output,
1560        }
1561        .into();
1562
1563        if let Some(snapshot) = snapshot
1564            && ![token::Comma, token::Gt, token::Plus].contains(&self.token.kind)
1565        {
1566            // We would expect another bound or the end of type params by now. Most likely we've
1567            // encountered a `(` *not* representing `Trait()`, but rather the start of the `fn`'s
1568            // argument list where the generic param list wasn't properly closed.
1569            self.restore_snapshot(snapshot);
1570            return Ok(());
1571        }
1572
1573        *fn_path_segment = ast::PathSegment {
1574            ident: fn_path_segment.ident,
1575            args: Some(args),
1576            id: ast::DUMMY_NODE_ID,
1577        };
1578
1579        // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`.
1580        let mut generic_params = lifetimes
1581            .iter()
1582            .map(|lt| GenericParam {
1583                id: lt.id,
1584                ident: lt.ident,
1585                attrs: ast::AttrVec::new(),
1586                bounds: ThinVec::new(),
1587                is_placeholder: false,
1588                kind: ast::GenericParamKind::Lifetime,
1589                colon_span: None,
1590            })
1591            .collect::<ThinVec<GenericParam>>();
1592        lifetime_defs.append(&mut generic_params);
1593
1594        let generic_args_span = generic_args.span();
1595        let snippet = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("for<{0}> ",
                lifetimes.iter().map(|lt|
                                lt.ident.as_str()).intersperse(", ").collect::<String>()))
    })format!(
1596            "for<{}> ",
1597            lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1598        );
1599        let before_fn_path = fn_path.span.shrink_to_lo();
1600        self.dcx()
1601            .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
1602            .with_multipart_suggestion(
1603                "consider using a higher-ranked trait bound instead",
1604                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(generic_args_span, "".to_owned()), (before_fn_path, snippet)]))vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1605                Applicability::MaybeIncorrect,
1606            )
1607            .emit();
1608        Ok(())
1609    }
1610
1611    pub(super) fn check_lifetime(&mut self) -> bool {
1612        self.expected_token_types.insert(TokenType::Lifetime);
1613        self.token.is_lifetime()
1614    }
1615
1616    /// Parses a single lifetime `'a` or panics.
1617    pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1618        if let Some((ident, is_raw)) = self.token.lifetime() {
1619            if is_raw == IdentIsRaw::No && ident.without_first_quote().is_reserved_lifetime() {
1620                self.dcx().emit_err(diagnostics::KeywordLifetime { span: ident.span });
1621            }
1622
1623            self.bump();
1624            Lifetime { ident, id: ast::DUMMY_NODE_ID }
1625        } else {
1626            self.dcx().span_bug(self.token.span, "not a lifetime")
1627        }
1628    }
1629
1630    pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> Box<Ty> {
1631        Box::new(Ty { kind, span, id: ast::DUMMY_NODE_ID })
1632    }
1633}