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