rustc_parse/parser/
ty.rs

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