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