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