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