]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/parser/ty.rs
Auto merge of #107541 - weihanglo:update-cargo, r=weihanglo
[rust.git] / compiler / rustc_parse / src / parser / ty.rs
1 use super::{Parser, PathStyle, TokenType};
2
3 use crate::errors::{ExpectedFnPathFoundFnKeyword, FnPtrWithGenerics, FnPtrWithGenericsSugg};
4 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
5
6 use ast::DUMMY_NODE_ID;
7 use rustc_ast::ptr::P;
8 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
9 use rustc_ast::util::case::Case;
10 use rustc_ast::{
11     self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime,
12     MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
13 };
14 use rustc_ast_pretty::pprust;
15 use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
16 use rustc_span::source_map::Span;
17 use rustc_span::symbol::{kw, sym, Ident};
18 use rustc_span::Symbol;
19 use thin_vec::thin_vec;
20
21 /// Any `?` or `~const` modifiers that appear at the start of a bound.
22 struct BoundModifiers {
23     /// `?Trait`.
24     maybe: Option<Span>,
25
26     /// `~const Trait`.
27     maybe_const: Option<Span>,
28 }
29
30 impl BoundModifiers {
31     fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
32         match (self.maybe, self.maybe_const) {
33             (None, None) => TraitBoundModifier::None,
34             (Some(_), None) => TraitBoundModifier::Maybe,
35             (None, Some(_)) => TraitBoundModifier::MaybeConst,
36             (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
37         }
38     }
39 }
40
41 #[derive(Copy, Clone, PartialEq)]
42 pub(super) enum AllowPlus {
43     Yes,
44     No,
45 }
46
47 #[derive(PartialEq, Clone, Copy)]
48 pub(super) enum RecoverQPath {
49     Yes,
50     No,
51 }
52
53 #[derive(PartialEq, Clone, Copy)]
54 pub(super) enum RecoverQuestionMark {
55     Yes,
56     No,
57 }
58
59 #[derive(PartialEq, Clone, Copy)]
60 pub(super) enum RecoverAnonEnum {
61     Yes,
62     No,
63 }
64
65 /// Signals whether parsing a type should recover `->`.
66 ///
67 /// More specifically, when parsing a function like:
68 /// ```compile_fail
69 /// fn foo() => u8 { 0 }
70 /// fn bar(): u8 { 0 }
71 /// ```
72 /// The compiler will try to recover interpreting `foo() => u8` as `foo() -> u8` when calling
73 /// `parse_ty` with anything except `RecoverReturnSign::No`, and it will try to recover `bar(): u8`
74 /// as `bar() -> u8` when passing `RecoverReturnSign::Yes` to `parse_ty`
75 #[derive(Copy, Clone, PartialEq)]
76 pub(super) enum RecoverReturnSign {
77     Yes,
78     OnlyFatArrow,
79     No,
80 }
81
82 impl RecoverReturnSign {
83     /// [RecoverReturnSign::Yes] allows for recovering `fn foo() => u8` and `fn foo(): u8`,
84     /// [RecoverReturnSign::OnlyFatArrow] allows for recovering only `fn foo() => u8` (recovering
85     /// colons can cause problems when parsing where clauses), and
86     /// [RecoverReturnSign::No] doesn't allow for any recovery of the return type arrow
87     fn can_recover(self, token: &TokenKind) -> bool {
88         match self {
89             Self::Yes => matches!(token, token::FatArrow | token::Colon),
90             Self::OnlyFatArrow => matches!(token, token::FatArrow),
91             Self::No => false,
92         }
93     }
94 }
95
96 // Is `...` (`CVarArgs`) legal at this level of type parsing?
97 #[derive(PartialEq, Clone, Copy)]
98 enum AllowCVariadic {
99     Yes,
100     No,
101 }
102
103 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
104 /// `IDENT<<u8 as Trait>::AssocTy>`.
105 ///
106 /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
107 /// that `IDENT` is not the ident of a fn trait.
108 fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
109     t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl)
110 }
111
112 impl<'a> Parser<'a> {
113     /// Parses a type.
114     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
115         self.parse_ty_common(
116             AllowPlus::Yes,
117             AllowCVariadic::No,
118             RecoverQPath::Yes,
119             RecoverReturnSign::Yes,
120             None,
121             RecoverQuestionMark::Yes,
122             RecoverAnonEnum::No,
123         )
124     }
125
126     pub(super) fn parse_ty_with_generics_recovery(
127         &mut self,
128         ty_params: &Generics,
129     ) -> PResult<'a, P<Ty>> {
130         self.parse_ty_common(
131             AllowPlus::Yes,
132             AllowCVariadic::No,
133             RecoverQPath::Yes,
134             RecoverReturnSign::Yes,
135             Some(ty_params),
136             RecoverQuestionMark::Yes,
137             RecoverAnonEnum::No,
138         )
139     }
140
141     /// Parse a type suitable for a function or function pointer parameter.
142     /// The difference from `parse_ty` is that this version allows `...`
143     /// (`CVarArgs`) at the top level of the type.
144     pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
145         self.parse_ty_common(
146             AllowPlus::Yes,
147             AllowCVariadic::Yes,
148             RecoverQPath::Yes,
149             RecoverReturnSign::Yes,
150             None,
151             RecoverQuestionMark::Yes,
152             RecoverAnonEnum::Yes,
153         )
154     }
155
156     /// Parses a type in restricted contexts where `+` is not permitted.
157     ///
158     /// Example 1: `&'a TYPE`
159     ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
160     /// Example 2: `value1 as TYPE + value2`
161     ///     `+` is prohibited to avoid interactions with expression grammar.
162     pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
163         self.parse_ty_common(
164             AllowPlus::No,
165             AllowCVariadic::No,
166             RecoverQPath::Yes,
167             RecoverReturnSign::Yes,
168             None,
169             RecoverQuestionMark::Yes,
170             RecoverAnonEnum::No,
171         )
172     }
173
174     /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
175     /// for better diagnostics involving `?`.
176     pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
177         self.parse_ty_common(
178             AllowPlus::No,
179             AllowCVariadic::No,
180             RecoverQPath::Yes,
181             RecoverReturnSign::Yes,
182             None,
183             RecoverQuestionMark::No,
184             RecoverAnonEnum::No,
185         )
186     }
187
188     pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
189         self.parse_ty_common(
190             AllowPlus::Yes,
191             AllowCVariadic::No,
192             RecoverQPath::Yes,
193             RecoverReturnSign::Yes,
194             None,
195             RecoverQuestionMark::No,
196             RecoverAnonEnum::No,
197         )
198     }
199
200     /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
201     pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
202         self.parse_ty_common(
203             AllowPlus::Yes,
204             AllowCVariadic::Yes,
205             RecoverQPath::Yes,
206             RecoverReturnSign::OnlyFatArrow,
207             None,
208             RecoverQuestionMark::Yes,
209             RecoverAnonEnum::No,
210         )
211     }
212
213     /// Parses an optional return type `[ -> TY ]` in a function declaration.
214     pub(super) fn parse_ret_ty(
215         &mut self,
216         allow_plus: AllowPlus,
217         recover_qpath: RecoverQPath,
218         recover_return_sign: RecoverReturnSign,
219     ) -> PResult<'a, FnRetTy> {
220         Ok(if self.eat(&token::RArrow) {
221             // FIXME(Centril): Can we unconditionally `allow_plus`?
222             let ty = self.parse_ty_common(
223                 allow_plus,
224                 AllowCVariadic::No,
225                 recover_qpath,
226                 recover_return_sign,
227                 None,
228                 RecoverQuestionMark::Yes,
229                 RecoverAnonEnum::Yes,
230             )?;
231             FnRetTy::Ty(ty)
232         } else if recover_return_sign.can_recover(&self.token.kind) {
233             // Don't `eat` to prevent `=>` from being added as an expected token which isn't
234             // actually expected and could only confuse users
235             self.bump();
236             self.struct_span_err(self.prev_token.span, "return types are denoted using `->`")
237                 .span_suggestion_short(
238                     self.prev_token.span,
239                     "use `->` instead",
240                     "->",
241                     Applicability::MachineApplicable,
242                 )
243                 .emit();
244             let ty = self.parse_ty_common(
245                 allow_plus,
246                 AllowCVariadic::No,
247                 recover_qpath,
248                 recover_return_sign,
249                 None,
250                 RecoverQuestionMark::Yes,
251                 RecoverAnonEnum::Yes,
252             )?;
253             FnRetTy::Ty(ty)
254         } else {
255             FnRetTy::Default(self.token.span.shrink_to_lo())
256         })
257     }
258
259     fn parse_ty_common(
260         &mut self,
261         allow_plus: AllowPlus,
262         allow_c_variadic: AllowCVariadic,
263         recover_qpath: RecoverQPath,
264         recover_return_sign: RecoverReturnSign,
265         ty_generics: Option<&Generics>,
266         recover_question_mark: RecoverQuestionMark,
267         recover_anon_enum: RecoverAnonEnum,
268     ) -> PResult<'a, P<Ty>> {
269         let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
270         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
271         maybe_whole!(self, NtTy, |x| x);
272
273         let lo = self.token.span;
274         let mut impl_dyn_multi = false;
275         let kind = if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
276             self.parse_ty_tuple_or_parens(lo, allow_plus)?
277         } else if self.eat(&token::Not) {
278             // Never type `!`
279             TyKind::Never
280         } else if self.eat(&token::BinOp(token::Star)) {
281             self.parse_ty_ptr()?
282         } else if self.eat(&token::OpenDelim(Delimiter::Bracket)) {
283             self.parse_array_or_slice_ty()?
284         } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
285             // Reference
286             self.expect_and()?;
287             self.parse_borrowed_pointee()?
288         } else if self.eat_keyword_noexpect(kw::Typeof) {
289             self.parse_typeof_ty()?
290         } else if self.eat_keyword(kw::Underscore) {
291             // A type to be inferred `_`
292             TyKind::Infer
293         } else if self.check_fn_front_matter(false, Case::Sensitive) {
294             // Function pointer type
295             self.parse_ty_bare_fn(lo, Vec::new(), None, recover_return_sign)?
296         } else if self.check_keyword(kw::For) {
297             // Function pointer type or bound list (trait object type) starting with a poly-trait.
298             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
299             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
300             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
301             if self.check_fn_front_matter(false, Case::Sensitive) {
302                 self.parse_ty_bare_fn(
303                     lo,
304                     lifetime_defs,
305                     Some(self.prev_token.span.shrink_to_lo()),
306                     recover_return_sign,
307                 )?
308             } else {
309                 let path = self.parse_path(PathStyle::Type)?;
310                 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
311                 self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
312             }
313         } else if self.eat_keyword(kw::Impl) {
314             self.parse_impl_ty(&mut impl_dyn_multi)?
315         } else if self.is_explicit_dyn_type() {
316             self.parse_dyn_ty(&mut impl_dyn_multi)?
317         } else if self.eat_lt() {
318             // Qualified path
319             let (qself, path) = self.parse_qpath(PathStyle::Type)?;
320             TyKind::Path(Some(qself), path)
321         } else if self.check_path() {
322             self.parse_path_start_ty(lo, allow_plus, ty_generics)?
323         } else if self.can_begin_bound() {
324             self.parse_bare_trait_object(lo, allow_plus)?
325         } else if self.eat(&token::DotDotDot) {
326             match allow_c_variadic {
327                 AllowCVariadic::Yes => TyKind::CVarArgs,
328                 AllowCVariadic::No => {
329                     // FIXME(Centril): Should we just allow `...` syntactically
330                     // anywhere in a type and use semantic restrictions instead?
331                     self.error_illegal_c_varadic_ty(lo);
332                     TyKind::Err
333                 }
334             }
335         } else {
336             let msg = format!("expected type, found {}", super::token_descr(&self.token));
337             let mut err = self.struct_span_err(self.token.span, &msg);
338             err.span_label(self.token.span, "expected type");
339             self.maybe_annotate_with_ascription(&mut err, true);
340             return Err(err);
341         };
342
343         let span = lo.to(self.prev_token.span);
344         let mut ty = self.mk_ty(span, kind);
345
346         // Try to recover from use of `+` with incorrect priority.
347         match allow_plus {
348             AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
349             AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
350         }
351         if RecoverQuestionMark::Yes == recover_question_mark {
352             ty = self.maybe_recover_from_question_mark(ty);
353         }
354         if recover_anon_enum == RecoverAnonEnum::Yes
355             && self.check_noexpect(&token::BinOp(token::Or))
356             && self.look_ahead(1, |t| t.can_begin_type())
357         {
358             let mut pipes = vec![self.token.span];
359             let mut types = vec![ty];
360             loop {
361                 if !self.eat(&token::BinOp(token::Or)) {
362                     break;
363                 }
364                 pipes.push(self.prev_token.span);
365                 types.push(self.parse_ty_common(
366                     allow_plus,
367                     allow_c_variadic,
368                     recover_qpath,
369                     recover_return_sign,
370                     ty_generics,
371                     recover_question_mark,
372                     RecoverAnonEnum::No,
373                 )?);
374             }
375             let mut err = self.struct_span_err(pipes, "anonymous enums are not supported");
376             for ty in &types {
377                 err.span_label(ty.span, "");
378             }
379             err.help(&format!(
380                 "create a named `enum` and use it here instead:\nenum Name {{\n{}\n}}",
381                 types
382                     .iter()
383                     .enumerate()
384                     .map(|(i, t)| format!(
385                         "    Variant{}({}),",
386                         i + 1, // Lets not confuse people with zero-indexing :)
387                         pprust::to_string(|s| s.print_type(&t)),
388                     ))
389                     .collect::<Vec<_>>()
390                     .join("\n"),
391             ));
392             err.emit();
393             return Ok(self.mk_ty(lo.to(self.prev_token.span), TyKind::Err));
394         }
395         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
396     }
397
398     /// Parses either:
399     /// - `(TYPE)`, a parenthesized type.
400     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
401     fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
402         let mut trailing_plus = false;
403         let (ts, trailing) = self.parse_paren_comma_seq(|p| {
404             let ty = p.parse_ty()?;
405             trailing_plus = p.prev_token.kind == TokenKind::BinOp(token::Plus);
406             Ok(ty)
407         })?;
408
409         if ts.len() == 1 && !trailing {
410             let ty = ts.into_iter().next().unwrap().into_inner();
411             let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
412             match ty.kind {
413                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
414                 TyKind::Path(None, path) if maybe_bounds => {
415                     self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
416                 }
417                 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
418                     if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
419                 {
420                     self.parse_remaining_bounds(bounds, true)
421                 }
422                 // `(TYPE)`
423                 _ => Ok(TyKind::Paren(P(ty))),
424             }
425         } else {
426             Ok(TyKind::Tup(ts))
427         }
428     }
429
430     fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
431         let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
432         let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
433         if lt_no_plus {
434             self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`")
435                 .emit();
436         }
437         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
438     }
439
440     fn parse_remaining_bounds_path(
441         &mut self,
442         generic_params: Vec<GenericParam>,
443         path: ast::Path,
444         lo: Span,
445         parse_plus: bool,
446     ) -> PResult<'a, TyKind> {
447         let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
448         let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
449         self.parse_remaining_bounds(bounds, parse_plus)
450     }
451
452     /// Parse the remainder of a bare trait object type given an already parsed list.
453     fn parse_remaining_bounds(
454         &mut self,
455         mut bounds: GenericBounds,
456         plus: bool,
457     ) -> PResult<'a, TyKind> {
458         if plus {
459             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
460             bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?);
461         }
462         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
463     }
464
465     /// Parses a raw pointer type: `*[const | mut] $type`.
466     fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
467         let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
468             let span = self.prev_token.span;
469             self.struct_span_err(span, "expected `mut` or `const` keyword in raw pointer type")
470                 .span_suggestions(
471                     span.shrink_to_hi(),
472                     "add `mut` or `const` here",
473                     ["mut ".to_string(), "const ".to_string()],
474                     Applicability::HasPlaceholders,
475                 )
476                 .emit();
477             Mutability::Not
478         });
479         let ty = self.parse_ty_no_plus()?;
480         Ok(TyKind::Ptr(MutTy { ty, mutbl }))
481     }
482
483     /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
484     /// The opening `[` bracket is already eaten.
485     fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
486         let elt_ty = match self.parse_ty() {
487             Ok(ty) => ty,
488             Err(mut err)
489                 if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket))
490                     | self.look_ahead(1, |t| t.kind == token::Semi) =>
491             {
492                 // Recover from `[LIT; EXPR]` and `[LIT]`
493                 self.bump();
494                 err.emit();
495                 self.mk_ty(self.prev_token.span, TyKind::Err)
496             }
497             Err(err) => return Err(err),
498         };
499
500         let ty = if self.eat(&token::Semi) {
501             let mut length = self.parse_anon_const_expr()?;
502             if let Err(e) = self.expect(&token::CloseDelim(Delimiter::Bracket)) {
503                 // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
504                 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
505                 self.expect(&token::CloseDelim(Delimiter::Bracket))?;
506             }
507             TyKind::Array(elt_ty, length)
508         } else {
509             self.expect(&token::CloseDelim(Delimiter::Bracket))?;
510             TyKind::Slice(elt_ty)
511         };
512
513         Ok(ty)
514     }
515
516     fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
517         let and_span = self.prev_token.span;
518         let mut opt_lifetime =
519             if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
520         let mut mutbl = self.parse_mutability();
521         if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
522             // A lifetime is invalid here: it would be part of a bare trait bound, which requires
523             // it to be followed by a plus, but we disallow plus in the pointee type.
524             // So we can handle this case as an error here, and suggest `'a mut`.
525             // If there *is* a plus next though, handling the error later provides better suggestions
526             // (like adding parentheses)
527             if !self.look_ahead(1, |t| t.is_like_plus()) {
528                 let lifetime_span = self.token.span;
529                 let span = and_span.to(lifetime_span);
530
531                 let mut err = self.struct_span_err(span, "lifetime must precede `mut`");
532                 if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
533                     err.span_suggestion(
534                         span,
535                         "place the lifetime before `mut`",
536                         format!("&{} mut", lifetime_src),
537                         Applicability::MaybeIncorrect,
538                     );
539                 }
540                 err.emit();
541
542                 opt_lifetime = Some(self.expect_lifetime());
543             }
544         } else if self.token.is_keyword(kw::Dyn)
545             && mutbl == Mutability::Not
546             && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
547         {
548             // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
549             let span = and_span.to(self.look_ahead(1, |t| t.span));
550             let mut err = self.struct_span_err(span, "`mut` must precede `dyn`");
551             err.span_suggestion(
552                 span,
553                 "place `mut` before `dyn`",
554                 "&mut dyn",
555                 Applicability::MachineApplicable,
556             );
557             err.emit();
558
559             // Recovery
560             mutbl = Mutability::Mut;
561             let (dyn_tok, dyn_tok_sp) = (self.token.clone(), self.token_spacing);
562             self.bump();
563             self.bump_with((dyn_tok, dyn_tok_sp));
564         }
565         let ty = self.parse_ty_no_plus()?;
566         Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }))
567     }
568
569     // Parses the `typeof(EXPR)`.
570     // To avoid ambiguity, the type is surrounded by parentheses.
571     fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
572         self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
573         let expr = self.parse_anon_const_expr()?;
574         self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
575         Ok(TyKind::Typeof(expr))
576     }
577
578     /// Parses a function pointer type (`TyKind::BareFn`).
579     /// ```ignore (illustrative)
580     ///    [unsafe] [extern "ABI"] fn (S) -> T
581     /// //  ^~~~~^          ^~~~^     ^~^    ^
582     /// //    |               |        |     |
583     /// //    |               |        |   Return type
584     /// // Function Style    ABI  Parameter types
585     /// ```
586     /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
587     fn parse_ty_bare_fn(
588         &mut self,
589         lo: Span,
590         mut params: Vec<GenericParam>,
591         param_insertion_point: Option<Span>,
592         recover_return_sign: RecoverReturnSign,
593     ) -> PResult<'a, TyKind> {
594         let inherited_vis = rustc_ast::Visibility {
595             span: rustc_span::DUMMY_SP,
596             kind: rustc_ast::VisibilityKind::Inherited,
597             tokens: None,
598         };
599         let span_start = self.token.span;
600         let ast::FnHeader { ext, unsafety, constness, asyncness } =
601             self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
602         if self.may_recover() && self.token.kind == TokenKind::Lt {
603             self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
604         }
605         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
606         let whole_span = lo.to(self.prev_token.span);
607         if let ast::Const::Yes(span) = constness {
608             // If we ever start to allow `const fn()`, then update
609             // feature gating for `#![feature(const_extern_fn)]` to
610             // cover it.
611             self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
612         }
613         if let ast::Async::Yes { span, .. } = asyncness {
614             self.error_fn_ptr_bad_qualifier(whole_span, span, "async");
615         }
616         let decl_span = span_start.to(self.token.span);
617         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
618     }
619
620     /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
621     fn recover_fn_ptr_with_generics(
622         &mut self,
623         lo: Span,
624         params: &mut Vec<GenericParam>,
625         param_insertion_point: Option<Span>,
626     ) -> PResult<'a, ()> {
627         let generics = self.parse_generics()?;
628         let arity = generics.params.len();
629
630         let mut lifetimes: Vec<_> = generics
631             .params
632             .into_iter()
633             .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
634             .collect();
635
636         let sugg = if !lifetimes.is_empty() {
637             let snippet =
638                 lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
639
640             let (left, snippet) = if let Some(span) = param_insertion_point {
641                 (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
642             } else {
643                 (lo.shrink_to_lo(), format!("for<{snippet}> "))
644             };
645
646             Some(FnPtrWithGenericsSugg {
647                 left,
648                 snippet,
649                 right: generics.span,
650                 arity,
651                 for_param_list_exists: param_insertion_point.is_some(),
652             })
653         } else {
654             None
655         };
656
657         self.sess.emit_err(FnPtrWithGenerics { span: generics.span, sugg });
658         params.append(&mut lifetimes);
659         Ok(())
660     }
661
662     /// Emit an error for the given bad function pointer qualifier.
663     fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) {
664         self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual))
665             .span_label(qual_span, format!("`{}` because of this", qual))
666             .span_suggestion_short(
667                 qual_span,
668                 &format!("remove the `{}` qualifier", qual),
669                 "",
670                 Applicability::MaybeIncorrect,
671             )
672             .emit();
673     }
674
675     /// Parses an `impl B0 + ... + Bn` type.
676     fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
677         // Always parse bounds greedily for better error recovery.
678         if self.token.is_lifetime() {
679             self.look_ahead(1, |t| {
680                 if let token::Ident(symname, _) = t.kind {
681                     // parse pattern with "'a Sized" we're supposed to give suggestion like
682                     // "'a + Sized"
683                     self.struct_span_err(
684                         self.token.span,
685                         &format!("expected `+` between lifetime and {}", symname),
686                     )
687                     .span_suggestion_verbose(
688                         self.token.span.shrink_to_hi(),
689                         "add `+`",
690                         " +",
691                         Applicability::MaybeIncorrect,
692                     )
693                     .emit();
694                 }
695             })
696         }
697         let bounds = self.parse_generic_bounds(None)?;
698         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
699         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
700     }
701
702     /// Is a `dyn B0 + ... + Bn` type allowed here?
703     fn is_explicit_dyn_type(&mut self) -> bool {
704         self.check_keyword(kw::Dyn)
705             && (!self.token.uninterpolated_span().rust_2015()
706                 || self.look_ahead(1, |t| {
707                     (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star))
708                         && !can_continue_type_after_non_fn_ident(t)
709                 }))
710     }
711
712     /// Parses a `dyn B0 + ... + Bn` type.
713     ///
714     /// Note that this does *not* parse bare trait objects.
715     fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
716         self.bump(); // `dyn`
717
718         // parse dyn* types
719         let syntax = if self.eat(&TokenKind::BinOp(token::Star)) {
720             TraitObjectSyntax::DynStar
721         } else {
722             TraitObjectSyntax::Dyn
723         };
724
725         // Always parse bounds greedily for better error recovery.
726         let bounds = self.parse_generic_bounds(None)?;
727         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
728         Ok(TyKind::TraitObject(bounds, syntax))
729     }
730
731     /// Parses a type starting with a path.
732     ///
733     /// This can be:
734     /// 1. a type macro, `mac!(...)`,
735     /// 2. a bare trait object, `B0 + ... + Bn`,
736     /// 3. or a path, `path::to::MyType`.
737     fn parse_path_start_ty(
738         &mut self,
739         lo: Span,
740         allow_plus: AllowPlus,
741         ty_generics: Option<&Generics>,
742     ) -> PResult<'a, TyKind> {
743         // Simple path
744         let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
745         if self.eat(&token::Not) {
746             // Macro invocation in type position
747             Ok(TyKind::MacCall(P(MacCall {
748                 path,
749                 args: self.parse_delim_args()?,
750                 prior_type_ascription: self.last_type_ascription,
751             })))
752         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
753             // `Trait1 + Trait2 + 'a`
754             self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
755         } else {
756             // Just a type path.
757             Ok(TyKind::Path(None, path))
758         }
759     }
760
761     fn error_illegal_c_varadic_ty(&self, lo: Span) {
762         struct_span_err!(
763             self.sess.span_diagnostic,
764             lo.to(self.prev_token.span),
765             E0743,
766             "C-variadic type `...` may not be nested inside another type",
767         )
768         .emit();
769     }
770
771     pub(super) fn parse_generic_bounds(
772         &mut self,
773         colon_span: Option<Span>,
774     ) -> PResult<'a, GenericBounds> {
775         self.parse_generic_bounds_common(AllowPlus::Yes, colon_span)
776     }
777
778     /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
779     ///
780     /// See `parse_generic_bound` for the `BOUND` grammar.
781     fn parse_generic_bounds_common(
782         &mut self,
783         allow_plus: AllowPlus,
784         colon_span: Option<Span>,
785     ) -> PResult<'a, GenericBounds> {
786         let mut bounds = Vec::new();
787         let mut negative_bounds = Vec::new();
788
789         // In addition to looping while we find generic bounds:
790         // We continue even if we find a keyword. This is necessary for error recovery on,
791         // for example, `impl fn()`. The only keyword that can go after generic bounds is
792         // `where`, so stop if it's it.
793         // We also continue if we find types (not traits), again for error recovery.
794         while self.can_begin_bound()
795             || self.token.can_begin_type()
796             || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
797         {
798             if self.token.is_keyword(kw::Dyn) {
799                 // Account for `&dyn Trait + dyn Other`.
800                 self.struct_span_err(self.token.span, "invalid `dyn` keyword")
801                     .help("`dyn` is only needed at the start of a trait `+`-separated list")
802                     .span_suggestion(
803                         self.token.span,
804                         "remove this keyword",
805                         "",
806                         Applicability::MachineApplicable,
807                     )
808                     .emit();
809                 self.bump();
810             }
811             match self.parse_generic_bound()? {
812                 Ok(bound) => bounds.push(bound),
813                 Err(neg_sp) => negative_bounds.push(neg_sp),
814             }
815             if allow_plus == AllowPlus::No || !self.eat_plus() {
816                 break;
817             }
818         }
819
820         if !negative_bounds.is_empty() {
821             self.error_negative_bounds(colon_span, &bounds, negative_bounds);
822         }
823
824         Ok(bounds)
825     }
826
827     /// Can the current token begin a bound?
828     fn can_begin_bound(&mut self) -> bool {
829         // This needs to be synchronized with `TokenKind::can_begin_bound`.
830         self.check_path()
831         || self.check_lifetime()
832         || self.check(&token::Not) // Used for error reporting only.
833         || self.check(&token::Question)
834         || self.check(&token::Tilde)
835         || self.check_keyword(kw::For)
836         || self.check(&token::OpenDelim(Delimiter::Parenthesis))
837     }
838
839     fn error_negative_bounds(
840         &self,
841         colon_span: Option<Span>,
842         bounds: &[GenericBound],
843         negative_bounds: Vec<Span>,
844     ) {
845         let negative_bounds_len = negative_bounds.len();
846         let last_span = *negative_bounds.last().expect("no negative bounds, but still error?");
847         let mut err = self.struct_span_err(negative_bounds, "negative bounds are not supported");
848         err.span_label(last_span, "negative bounds are not supported");
849         if let Some(bound_list) = colon_span {
850             let bound_list = bound_list.to(self.prev_token.span);
851             let mut new_bound_list = String::new();
852             if !bounds.is_empty() {
853                 let mut snippets = bounds.iter().map(|bound| self.span_to_snippet(bound.span()));
854                 while let Some(Ok(snippet)) = snippets.next() {
855                     new_bound_list.push_str(" + ");
856                     new_bound_list.push_str(&snippet);
857                 }
858                 new_bound_list = new_bound_list.replacen(" +", ":", 1);
859             }
860             err.tool_only_span_suggestion(
861                 bound_list,
862                 &format!("remove the bound{}", pluralize!(negative_bounds_len)),
863                 new_bound_list,
864                 Applicability::MachineApplicable,
865             );
866         }
867         err.emit();
868     }
869
870     /// Parses a bound according to the grammar:
871     /// ```ebnf
872     /// BOUND = TY_BOUND | LT_BOUND
873     /// ```
874     fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> {
875         let anchor_lo = self.prev_token.span;
876         let lo = self.token.span;
877         let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
878         let inner_lo = self.token.span;
879         let is_negative = self.eat(&token::Not);
880
881         let modifiers = self.parse_ty_bound_modifiers()?;
882         let bound = if self.token.is_lifetime() {
883             self.error_lt_bound_with_modifiers(modifiers);
884             self.parse_generic_lt_bound(lo, inner_lo, has_parens)?
885         } else {
886             self.parse_generic_ty_bound(lo, has_parens, modifiers)?
887         };
888
889         Ok(if is_negative { Err(anchor_lo.to(self.prev_token.span)) } else { Ok(bound) })
890     }
891
892     /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
893     /// ```ebnf
894     /// LT_BOUND = LIFETIME
895     /// ```
896     fn parse_generic_lt_bound(
897         &mut self,
898         lo: Span,
899         inner_lo: Span,
900         has_parens: bool,
901     ) -> PResult<'a, GenericBound> {
902         let bound = GenericBound::Outlives(self.expect_lifetime());
903         if has_parens {
904             // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
905             // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
906             self.recover_paren_lifetime(lo, inner_lo)?;
907         }
908         Ok(bound)
909     }
910
911     /// Emits an error if any trait bound modifiers were present.
912     fn error_lt_bound_with_modifiers(&self, modifiers: BoundModifiers) {
913         if let Some(span) = modifiers.maybe_const {
914             self.struct_span_err(
915                 span,
916                 "`~const` may only modify trait bounds, not lifetime bounds",
917             )
918             .emit();
919         }
920
921         if let Some(span) = modifiers.maybe {
922             self.struct_span_err(span, "`?` may only modify trait bounds, not lifetime bounds")
923                 .emit();
924         }
925     }
926
927     /// Recover on `('lifetime)` with `(` already eaten.
928     fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> {
929         let inner_span = inner_lo.to(self.prev_token.span);
930         self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
931         let mut err = self.struct_span_err(
932             lo.to(self.prev_token.span),
933             "parenthesized lifetime bounds are not supported",
934         );
935         if let Ok(snippet) = self.span_to_snippet(inner_span) {
936             err.span_suggestion_short(
937                 lo.to(self.prev_token.span),
938                 "remove the parentheses",
939                 snippet,
940                 Applicability::MachineApplicable,
941             );
942         }
943         err.emit();
944         Ok(())
945     }
946
947     /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `~const Trait`.
948     ///
949     /// If no modifiers are present, this does not consume any tokens.
950     ///
951     /// ```ebnf
952     /// TY_BOUND_MODIFIERS = ["~const"] ["?"]
953     /// ```
954     fn parse_ty_bound_modifiers(&mut self) -> PResult<'a, BoundModifiers> {
955         let maybe_const = if self.eat(&token::Tilde) {
956             let tilde = self.prev_token.span;
957             self.expect_keyword(kw::Const)?;
958             let span = tilde.to(self.prev_token.span);
959             self.sess.gated_spans.gate(sym::const_trait_impl, span);
960             Some(span)
961         } else if self.eat_keyword(kw::Const) {
962             let span = self.prev_token.span;
963             self.sess.gated_spans.gate(sym::const_trait_impl, span);
964
965             self.struct_span_err(span, "const bounds must start with `~`")
966                 .span_suggestion(
967                     span.shrink_to_lo(),
968                     "add `~`",
969                     "~",
970                     Applicability::MachineApplicable,
971                 )
972                 .emit();
973
974             Some(span)
975         } else {
976             None
977         };
978
979         let maybe = if self.eat(&token::Question) { Some(self.prev_token.span) } else { None };
980
981         Ok(BoundModifiers { maybe, maybe_const })
982     }
983
984     /// Parses a type bound according to:
985     /// ```ebnf
986     /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
987     /// TY_BOUND_NOPAREN = [TY_BOUND_MODIFIERS] [for<LT_PARAM_DEFS>] SIMPLE_PATH
988     /// ```
989     ///
990     /// For example, this grammar accepts `~const ?for<'a: 'b> m::Trait<'a>`.
991     fn parse_generic_ty_bound(
992         &mut self,
993         lo: Span,
994         has_parens: bool,
995         modifiers: BoundModifiers,
996     ) -> PResult<'a, GenericBound> {
997         let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?;
998         let mut path = if self.token.is_keyword(kw::Fn)
999             && self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
1000             && let Some(path) = self.recover_path_from_fn()
1001         {
1002             path
1003         } else if !self.token.is_path_start() && self.token.can_begin_type() {
1004             let ty = self.parse_ty_no_plus()?;
1005             // Instead of finding a path (a trait), we found a type.
1006             let mut err = self.struct_span_err(ty.span, "expected a trait, found type");
1007
1008             // If we can recover, try to extract a path from the type. Note
1009             // that we do not use the try operator when parsing the type because
1010             // if it fails then we get a parser error which we don't want (we're trying
1011             // to recover from errors, not make more).
1012             let path = if self.may_recover()
1013                 && matches!(ty.kind, TyKind::Ptr(..) | TyKind::Ref(..))
1014                 && let TyKind::Path(_, path) = &ty.peel_refs().kind {
1015                 // Just get the indirection part of the type.
1016                 let span = ty.span.until(path.span);
1017
1018                 err.span_suggestion_verbose(
1019                     span,
1020                     "consider removing the indirection",
1021                     "",
1022                     Applicability::MaybeIncorrect,
1023                 );
1024
1025                 path.clone()
1026             } else {
1027                 return Err(err);
1028             };
1029
1030             err.emit();
1031
1032             path
1033         } else {
1034             self.parse_path(PathStyle::Type)?
1035         };
1036
1037         if self.may_recover() && self.token == TokenKind::OpenDelim(Delimiter::Parenthesis) {
1038             self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
1039         }
1040
1041         if has_parens {
1042             if self.token.is_like_plus() {
1043                 // Someone has written something like `&dyn (Trait + Other)`. The correct code
1044                 // would be `&(dyn Trait + Other)`, but we don't have access to the appropriate
1045                 // span to suggest that. When written as `&dyn Trait + Other`, an appropriate
1046                 // suggestion is given.
1047                 let bounds = vec![];
1048                 self.parse_remaining_bounds(bounds, true)?;
1049                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
1050                 let sp = vec![lo, self.prev_token.span];
1051                 let sugg = vec![(lo, String::from(" ")), (self.prev_token.span, String::new())];
1052                 self.struct_span_err(sp, "incorrect braces around trait bounds")
1053                     .multipart_suggestion(
1054                         "remove the parentheses",
1055                         sugg,
1056                         Applicability::MachineApplicable,
1057                     )
1058                     .emit();
1059             } else {
1060                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
1061             }
1062         }
1063
1064         let modifier = modifiers.to_trait_bound_modifier();
1065         let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
1066         Ok(GenericBound::Trait(poly_trait, modifier))
1067     }
1068
1069     // recovers a `Fn(..)` parenthesized-style path from `fn(..)`
1070     fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1071         let fn_token_span = self.token.span;
1072         self.bump();
1073         let args_lo = self.token.span;
1074         let snapshot = self.create_snapshot_for_diagnostic();
1075         match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1076             Ok(decl) => {
1077                 self.sess.emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1078                 Some(ast::Path {
1079                     span: fn_token_span.to(self.prev_token.span),
1080                     segments: thin_vec![ast::PathSegment {
1081                         ident: Ident::new(Symbol::intern("Fn"), fn_token_span),
1082                         id: DUMMY_NODE_ID,
1083                         args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
1084                             span: args_lo.to(self.prev_token.span),
1085                             inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
1086                             inputs_span: args_lo.until(decl.output.span()),
1087                             output: decl.output.clone(),
1088                         }))),
1089                     }],
1090                     tokens: None,
1091                 })
1092             }
1093             Err(diag) => {
1094                 diag.cancel();
1095                 self.restore_snapshot(snapshot);
1096                 None
1097             }
1098         }
1099     }
1100
1101     /// Optionally parses `for<$generic_params>`.
1102     pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
1103         if self.eat_keyword(kw::For) {
1104             self.expect_lt()?;
1105             let params = self.parse_generic_params()?;
1106             self.expect_gt()?;
1107             // We rely on AST validation to rule out invalid cases: There must not be type
1108             // parameters, and the lifetime parameters must not have bounds.
1109             Ok(params)
1110         } else {
1111             Ok(Vec::new())
1112         }
1113     }
1114
1115     /// Recover from `Fn`-family traits (Fn, FnMut, FnOnce) with lifetime arguments
1116     /// (e.g. `FnOnce<'a>(&'a str) -> bool`). Up to generic arguments have already
1117     /// been eaten.
1118     fn recover_fn_trait_with_lifetime_params(
1119         &mut self,
1120         fn_path: &mut ast::Path,
1121         lifetime_defs: &mut Vec<GenericParam>,
1122     ) -> PResult<'a, ()> {
1123         let fn_path_segment = fn_path.segments.last_mut().unwrap();
1124         let generic_args = if let Some(p_args) = &fn_path_segment.args {
1125             p_args.clone().into_inner()
1126         } else {
1127             // Normally it wouldn't come here because the upstream should have parsed
1128             // generic parameters (otherwise it's impossible to call this function).
1129             return Ok(());
1130         };
1131         let lifetimes =
1132             if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1133                 &generic_args
1134             {
1135                 args.into_iter()
1136                     .filter_map(|arg| {
1137                         if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1138                             && let ast::GenericArg::Lifetime(lifetime) = generic_arg {
1139                             Some(lifetime)
1140                         } else {
1141                             None
1142                         }
1143                     })
1144                     .collect()
1145             } else {
1146                 Vec::new()
1147             };
1148         // Only try to recover if the trait has lifetime params.
1149         if lifetimes.is_empty() {
1150             return Ok(());
1151         }
1152
1153         // Parse `(T, U) -> R`.
1154         let inputs_lo = self.token.span;
1155         let inputs: Vec<_> =
1156             self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
1157         let inputs_span = inputs_lo.to(self.prev_token.span);
1158         let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
1159         let args = ast::ParenthesizedArgs {
1160             span: fn_path_segment.span().to(self.prev_token.span),
1161             inputs,
1162             inputs_span,
1163             output,
1164         }
1165         .into();
1166         *fn_path_segment =
1167             ast::PathSegment { ident: fn_path_segment.ident, args, id: ast::DUMMY_NODE_ID };
1168
1169         // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`.
1170         let mut generic_params = lifetimes
1171             .iter()
1172             .map(|lt| GenericParam {
1173                 id: lt.id,
1174                 ident: lt.ident,
1175                 attrs: ast::AttrVec::new(),
1176                 bounds: Vec::new(),
1177                 is_placeholder: false,
1178                 kind: ast::GenericParamKind::Lifetime,
1179                 colon_span: None,
1180             })
1181             .collect::<Vec<GenericParam>>();
1182         lifetime_defs.append(&mut generic_params);
1183
1184         let generic_args_span = generic_args.span();
1185         let mut err =
1186             self.struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters");
1187         let snippet = format!(
1188             "for<{}> ",
1189             lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1190         );
1191         let before_fn_path = fn_path.span.shrink_to_lo();
1192         err.multipart_suggestion(
1193             "consider using a higher-ranked trait bound instead",
1194             vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1195             Applicability::MaybeIncorrect,
1196         )
1197         .emit();
1198         Ok(())
1199     }
1200
1201     pub(super) fn check_lifetime(&mut self) -> bool {
1202         self.expected_tokens.push(TokenType::Lifetime);
1203         self.token.is_lifetime()
1204     }
1205
1206     /// Parses a single lifetime `'a` or panics.
1207     pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1208         if let Some(ident) = self.token.lifetime() {
1209             self.bump();
1210             Lifetime { ident, id: ast::DUMMY_NODE_ID }
1211         } else {
1212             self.span_bug(self.token.span, "not a lifetime")
1213         }
1214     }
1215
1216     pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
1217         P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1218     }
1219 }