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