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