rustc_parse/parser/
ty.rs

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