rustc_parse/parser/
ty.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy