1use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind};
2use rustc_ast::util::case::Case;
3use rustc_ast::{
4 self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy,
5 GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MgcaDisambiguation,
6 MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers,
7 TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy,
8};
9use rustc_data_structures::stack::ensure_sufficient_stack;
10use rustc_errors::{Applicability, Diag, E0516, PResult};
11use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
12use thin_vec::{ThinVec, thin_vec};
13
14use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
15use crate::errors::{
16 self, AttributeOnEmptyType, AttributeOnType, DynAfterMut, ExpectedFnPathFoundFnKeyword,
17 ExpectedMutOrConstInRawPointerType, FnPtrWithGenerics, FnPtrWithGenericsSugg,
18 HelpUseLatestEdition, InvalidCVariadicType, InvalidDynKeyword, LifetimeAfterMut,
19 NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow,
20};
21use crate::parser::item::FrontMatterParsingMode;
22use crate::parser::{FnContext, FnParseMode};
23use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
24
25#[derive(Copy, Clone, PartialEq)]
31pub(super) enum AllowPlus {
32 Yes,
33 No,
34}
35
36#[derive(PartialEq)]
37pub(super) enum RecoverQPath {
38 Yes,
39 No,
40}
41
42pub(super) enum RecoverQuestionMark {
43 Yes,
44 No,
45}
46
47#[derive(Copy, Clone, PartialEq)]
58pub(super) enum RecoverReturnSign {
59 Yes,
60 OnlyFatArrow,
61 No,
62}
63
64impl RecoverReturnSign {
65 fn can_recover(self, token: &TokenKind) -> bool {
70 match self {
71 Self::Yes => matches!(token, token::FatArrow | token::Colon),
72 Self::OnlyFatArrow => matches!(token, token::FatArrow),
73 Self::No => false,
74 }
75 }
76}
77
78#[derive(PartialEq)]
80enum AllowCVariadic {
81 Yes,
82 No,
83}
84
85fn can_begin_dyn_bound_in_edition_2015(t: Token) -> bool {
89 if t.is_path_start() {
90 return t != token::PathSep && t != token::Lt && t != token::Shl;
96 }
97
98 t == token::OpenParen || t == token::Question || t.is_lifetime() || t.is_keyword(kw::For)
103}
104
105impl<'a> Parser<'a> {
106 pub fn parse_ty(&mut self) -> PResult<'a, Box<Ty>> {
108 if self.token == token::DotDotDot {
109 let span = self.token.span;
113 self.bump();
114 let kind = TyKind::Err(self.dcx().emit_err(InvalidCVariadicType { span }));
115 return Ok(self.mk_ty(span, kind));
116 }
117 ensure_sufficient_stack(|| {
119 self.parse_ty_common(
120 AllowPlus::Yes,
121 AllowCVariadic::No,
122 RecoverQPath::Yes,
123 RecoverReturnSign::Yes,
124 None,
125 RecoverQuestionMark::Yes,
126 )
127 })
128 }
129
130 pub(super) fn parse_ty_with_generics_recovery(
131 &mut self,
132 ty_params: &Generics,
133 ) -> PResult<'a, Box<Ty>> {
134 self.parse_ty_common(
135 AllowPlus::Yes,
136 AllowCVariadic::No,
137 RecoverQPath::Yes,
138 RecoverReturnSign::Yes,
139 Some(ty_params),
140 RecoverQuestionMark::Yes,
141 )
142 }
143
144 pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, Box<Ty>> {
148 let ty = self.parse_ty_common(
149 AllowPlus::Yes,
150 AllowCVariadic::Yes,
151 RecoverQPath::Yes,
152 RecoverReturnSign::Yes,
153 None,
154 RecoverQuestionMark::Yes,
155 )?;
156
157 if self.may_recover()
159 && self.check_noexpect(&token::Eq)
160 && self.look_ahead(1, |tok| tok.can_begin_expr())
161 {
162 let snapshot = self.create_snapshot_for_diagnostic();
163 self.bump();
164 let eq_span = self.prev_token.span;
165 match self.parse_expr() {
166 Ok(e) => {
167 self.dcx()
168 .struct_span_err(eq_span.to(e.span), "parameter defaults are not supported")
169 .emit();
170 }
171 Err(diag) => {
172 diag.cancel();
173 self.restore_snapshot(snapshot);
174 }
175 }
176 }
177
178 Ok(ty)
179 }
180
181 pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, Box<Ty>> {
188 self.parse_ty_common(
189 AllowPlus::No,
190 AllowCVariadic::No,
191 RecoverQPath::Yes,
192 RecoverReturnSign::Yes,
193 None,
194 RecoverQuestionMark::Yes,
195 )
196 }
197
198 pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, Box<Ty>> {
201 self.parse_ty_common(
202 AllowPlus::No,
203 AllowCVariadic::No,
204 RecoverQPath::Yes,
205 RecoverReturnSign::Yes,
206 None,
207 RecoverQuestionMark::No,
208 )
209 }
210
211 pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, Box<Ty>> {
212 self.parse_ty_common(
213 AllowPlus::Yes,
214 AllowCVariadic::No,
215 RecoverQPath::Yes,
216 RecoverReturnSign::Yes,
217 None,
218 RecoverQuestionMark::No,
219 )
220 }
221
222 pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, Box<Ty>> {
225 self.parse_ty_common(
226 AllowPlus::Yes,
227 AllowCVariadic::No,
228 RecoverQPath::Yes,
229 RecoverReturnSign::OnlyFatArrow,
230 None,
231 RecoverQuestionMark::Yes,
232 )
233 }
234
235 pub(super) fn parse_ret_ty(
237 &mut self,
238 allow_plus: AllowPlus,
239 recover_qpath: RecoverQPath,
240 recover_return_sign: RecoverReturnSign,
241 ) -> PResult<'a, FnRetTy> {
242 let lo = self.prev_token.span;
243 Ok(if self.eat(exp!(RArrow)) {
244 let ty = self.parse_ty_common(
246 allow_plus,
247 AllowCVariadic::No,
248 recover_qpath,
249 recover_return_sign,
250 None,
251 RecoverQuestionMark::Yes,
252 )?;
253 FnRetTy::Ty(ty)
254 } else if recover_return_sign.can_recover(&self.token.kind) {
255 self.bump();
258 self.dcx().emit_err(ReturnTypesUseThinArrow {
259 span: self.prev_token.span,
260 suggestion: lo.between(self.token.span),
261 });
262 let ty = self.parse_ty_common(
263 allow_plus,
264 AllowCVariadic::No,
265 recover_qpath,
266 recover_return_sign,
267 None,
268 RecoverQuestionMark::Yes,
269 )?;
270 FnRetTy::Ty(ty)
271 } else {
272 FnRetTy::Default(self.prev_token.span.shrink_to_hi())
273 })
274 }
275
276 fn parse_ty_common(
277 &mut self,
278 allow_plus: AllowPlus,
279 allow_c_variadic: AllowCVariadic,
280 recover_qpath: RecoverQPath,
281 recover_return_sign: RecoverReturnSign,
282 ty_generics: Option<&Generics>,
283 recover_question_mark: RecoverQuestionMark,
284 ) -> PResult<'a, Box<Ty>> {
285 let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
286 maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
287 if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) {
288 let attrs_wrapper = self.parse_outer_attributes()?;
289 let raw_attrs = attrs_wrapper.take_for_recovery(self.psess);
290 let attr_span = raw_attrs[0].span.to(raw_attrs.last().unwrap().span);
291 let (full_span, guar) = match self.parse_ty() {
292 Ok(ty) => {
293 let full_span = attr_span.until(ty.span);
294 let guar = self
295 .dcx()
296 .emit_err(AttributeOnType { span: attr_span, fix_span: full_span });
297 (attr_span, guar)
298 }
299 Err(err) => {
300 err.cancel();
301 let guar = self.dcx().emit_err(AttributeOnEmptyType { span: attr_span });
302 (attr_span, guar)
303 }
304 };
305
306 return Ok(self.mk_ty(full_span, TyKind::Err(guar)));
307 }
308 if let Some(ty) = self.eat_metavar_seq_with_matcher(
309 |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }),
310 |this| this.parse_ty_no_question_mark_recover(),
311 ) {
312 return Ok(ty);
313 }
314
315 let lo = self.token.span;
316 let mut impl_dyn_multi = false;
317 let kind = if self.check(exp!(OpenParen)) {
318 self.parse_ty_tuple_or_parens(lo, allow_plus)?
319 } else if self.eat(exp!(Bang)) {
320 TyKind::Never
322 } else if self.eat(exp!(Star)) {
323 self.parse_ty_ptr()?
324 } else if self.eat(exp!(OpenBracket)) {
325 self.parse_array_or_slice_ty()?
326 } else if self.check(exp!(And)) || self.check(exp!(AndAnd)) {
327 self.expect_and()?;
329 self.parse_borrowed_pointee()?
330 } else if self.eat_keyword_noexpect(kw::Typeof) {
331 self.parse_typeof_ty(lo)?
332 } else if self.eat_keyword(exp!(Underscore)) {
333 TyKind::Infer
335 } else if self.check_fn_front_matter(false, Case::Sensitive) {
336 self.parse_ty_fn_ptr(lo, ThinVec::new(), None, recover_return_sign)?
338 } else if self.check_keyword(exp!(For)) {
339 let (bound_vars, _) = self.parse_higher_ranked_binder()?;
343 if self.check_fn_front_matter(false, Case::Sensitive) {
344 self.parse_ty_fn_ptr(
345 lo,
346 bound_vars,
347 Some(self.prev_token.span.shrink_to_lo()),
348 recover_return_sign,
349 )?
350 } else {
351 if self.may_recover()
353 && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn))
354 {
355 let kw = self.prev_token.ident().unwrap().0;
356 let removal_span = kw.span.with_hi(self.token.span.lo());
357 let path = self.parse_path(PathStyle::Type)?;
358 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
359 let kind = self.parse_remaining_bounds_path(
360 bound_vars,
361 path,
362 lo,
363 parse_plus,
364 ast::Parens::No,
365 )?;
366 let err = self.dcx().create_err(errors::TransposeDynOrImpl {
367 span: kw.span,
368 kw: kw.name.as_str(),
369 sugg: errors::TransposeDynOrImplSugg {
370 removal_span,
371 insertion_span: lo.shrink_to_lo(),
372 kw: kw.name.as_str(),
373 },
374 });
375
376 let kind = match (kind, kw.name) {
379 (TyKind::TraitObject(bounds, _), kw::Dyn) => {
380 TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
381 }
382 (TyKind::TraitObject(bounds, _), kw::Impl) => {
383 TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
384 }
385 _ => return Err(err),
386 };
387 err.emit();
388 kind
389 } else {
390 let path = self.parse_path(PathStyle::Type)?;
391 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
392 self.parse_remaining_bounds_path(
393 bound_vars,
394 path,
395 lo,
396 parse_plus,
397 ast::Parens::No,
398 )?
399 }
400 }
401 } else if self.eat_keyword(exp!(Impl)) {
402 self.parse_impl_ty(&mut impl_dyn_multi)?
403 } else if self.is_explicit_dyn_type() {
404 self.parse_dyn_ty(&mut impl_dyn_multi)?
405 } else if self.eat_lt() {
406 let (qself, path) = self.parse_qpath(PathStyle::Type)?;
408 TyKind::Path(Some(qself), path)
409 } else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut))
410 && self.look_ahead(1, |t| *t == token::Star)
411 {
412 self.parse_ty_c_style_pointer()?
413 } else if self.check_path() {
414 self.parse_path_start_ty(lo, allow_plus, ty_generics)?
415 } else if self.can_begin_bound() {
416 self.parse_bare_trait_object(lo, allow_plus)?
417 } else if self.eat(exp!(DotDotDot)) {
418 match allow_c_variadic {
419 AllowCVariadic::Yes => TyKind::CVarArgs,
420 AllowCVariadic::No => {
421 let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
425 TyKind::Err(guar)
426 }
427 }
428 } else if self.check_keyword(exp!(Unsafe))
429 && self.look_ahead(1, |tok| tok.kind == token::Lt)
430 {
431 self.parse_unsafe_binder_ty()?
432 } else {
433 let msg = format!("expected type, found {}", super::token_descr(&self.token));
434 let mut err = self.dcx().struct_span_err(lo, msg);
435 err.span_label(lo, "expected type");
436 return Err(err);
437 };
438
439 let span = lo.to(self.prev_token.span);
440 let mut ty = self.mk_ty(span, kind);
441
442 match allow_plus {
444 AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
445 AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
446 }
447 if let RecoverQuestionMark::Yes = recover_question_mark {
448 ty = self.maybe_recover_from_question_mark(ty);
449 }
450 if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
451 }
452
453 fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
454 let lo = self.token.span;
455 assert!(self.eat_keyword(exp!(Unsafe)));
456 self.expect_lt()?;
457 let generic_params = self.parse_generic_params()?;
458 self.expect_gt()?;
459 let inner_ty = self.parse_ty()?;
460 let span = lo.to(self.prev_token.span);
461 self.psess.gated_spans.gate(sym::unsafe_binders, span);
462
463 Ok(TyKind::UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, inner_ty })))
464 }
465
466 fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
470 let mut trailing_plus = false;
471 let (ts, trailing) = self.parse_paren_comma_seq(|p| {
472 let ty = p.parse_ty()?;
473 trailing_plus = p.prev_token == TokenKind::Plus;
474 Ok(ty)
475 })?;
476
477 if ts.len() == 1 && matches!(trailing, Trailing::No) {
478 let ty = ts.into_iter().next().unwrap();
479 let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
480 match ty.kind {
481 TyKind::Path(None, path) if maybe_bounds => self.parse_remaining_bounds_path(
483 ThinVec::new(),
484 path,
485 lo,
486 true,
487 ast::Parens::Yes,
488 ),
489 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
493 if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
494 {
495 self.parse_remaining_bounds(bounds, true)
496 }
497 _ => Ok(TyKind::Paren(ty)),
499 }
500 } else {
501 Ok(TyKind::Tup(ts))
502 }
503 }
504
505 fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
506 if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) {
508 if self.psess.edition.at_least_rust_2021() {
512 let lt = self.expect_lifetime();
513 let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime");
514 err.span_label(lo, "expected type");
515 return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) {
516 Ok(ref_ty) => ref_ty,
517 Err(err) => TyKind::Err(err.emit()),
518 });
519 }
520
521 self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime {
522 span: lo,
523 suggestion: lo.shrink_to_hi(),
524 });
525 }
526 Ok(TyKind::TraitObject(
527 self.parse_generic_bounds_common(allow_plus)?,
528 TraitObjectSyntax::None,
529 ))
530 }
531
532 fn maybe_recover_ref_ty_no_leading_ampersand<'cx>(
533 &mut self,
534 lt: Lifetime,
535 lo: Span,
536 mut err: Diag<'cx>,
537 ) -> Result<TyKind, Diag<'cx>> {
538 if !self.may_recover() {
539 return Err(err);
540 }
541 let snapshot = self.create_snapshot_for_diagnostic();
542 let mutbl = self.parse_mutability();
543 match self.parse_ty_no_plus() {
544 Ok(ty) => {
545 err.span_suggestion_verbose(
546 lo.shrink_to_lo(),
547 "you might have meant to write a reference type here",
548 "&",
549 Applicability::MaybeIncorrect,
550 );
551 err.emit();
552 Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl }))
553 }
554 Err(diag) => {
555 diag.cancel();
556 self.restore_snapshot(snapshot);
557 Err(err)
558 }
559 }
560 }
561
562 fn parse_remaining_bounds_path(
563 &mut self,
564 generic_params: ThinVec<GenericParam>,
565 path: ast::Path,
566 lo: Span,
567 parse_plus: bool,
568 parens: ast::Parens,
569 ) -> PResult<'a, TyKind> {
570 let poly_trait_ref = PolyTraitRef::new(
571 generic_params,
572 path,
573 TraitBoundModifiers::NONE,
574 lo.to(self.prev_token.span),
575 parens,
576 );
577 let bounds = vec![GenericBound::Trait(poly_trait_ref)];
578 self.parse_remaining_bounds(bounds, parse_plus)
579 }
580
581 fn parse_remaining_bounds(
583 &mut self,
584 mut bounds: GenericBounds,
585 plus: bool,
586 ) -> PResult<'a, TyKind> {
587 if plus {
588 self.eat_plus(); bounds.append(&mut self.parse_generic_bounds()?);
590 }
591 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
592 }
593
594 fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> {
596 let kw_span = self.token.span;
597 let mutbl = self.parse_const_or_mut();
598
599 if let Some(mutbl) = mutbl
600 && self.eat(exp!(Star))
601 {
602 let star_span = self.prev_token.span;
603
604 let mutability = match mutbl {
605 Mutability::Not => "const",
606 Mutability::Mut => "mut",
607 };
608
609 let ty = self.parse_ty_no_question_mark_recover()?;
610
611 self.dcx()
612 .struct_span_err(
613 kw_span,
614 format!("raw pointer types must be written as `*{mutability} T`"),
615 )
616 .with_multipart_suggestion(
617 format!("put the `*` before `{mutability}`"),
618 vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())],
619 Applicability::MachineApplicable,
620 )
621 .emit();
622
623 return Ok(TyKind::Ptr(MutTy { ty, mutbl }));
624 }
625 unreachable!("this could never happen")
627 }
628
629 fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
631 let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
632 let span = self.prev_token.span;
633 self.dcx().emit_err(ExpectedMutOrConstInRawPointerType {
634 span,
635 after_asterisk: span.shrink_to_hi(),
636 });
637 Mutability::Not
638 });
639 let ty = self.parse_ty_no_plus()?;
640 Ok(TyKind::Ptr(MutTy { ty, mutbl }))
641 }
642
643 fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
646 let elt_ty = match self.parse_ty() {
647 Ok(ty) => ty,
648 Err(err)
649 if self.look_ahead(1, |t| *t == token::CloseBracket)
650 | self.look_ahead(1, |t| *t == token::Semi) =>
651 {
652 self.bump();
654 let guar = err.emit();
655 self.mk_ty(self.prev_token.span, TyKind::Err(guar))
656 }
657 Err(err) => return Err(err),
658 };
659
660 let ty = if self.eat(exp!(Semi)) {
661 let mut length = if self.token.is_keyword(kw::Const)
662 && self.look_ahead(1, |t| *t == token::OpenBrace)
663 {
664 self.parse_mgca_const_block(false)?
670 } else {
671 self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
672 };
673
674 if let Err(e) = self.expect(exp!(CloseBracket)) {
675 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
677 self.expect(exp!(CloseBracket))?;
678 }
679 TyKind::Array(elt_ty, length)
680 } else if self.eat(exp!(CloseBracket)) {
681 TyKind::Slice(elt_ty)
682 } else {
683 self.maybe_recover_array_ty_without_semi(elt_ty)?
684 };
685
686 Ok(ty)
687 }
688
689 fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: Box<Ty>) -> PResult<'a, TyKind> {
696 let span = self.token.span;
697 let token_descr = super::token_descr(&self.token);
698 let mut err =
699 self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr));
700 err.span_label(span, "expected `;` or `]`");
701
702 if !self.may_recover() {
704 return Err(err);
705 }
706
707 let snapshot = self.create_snapshot_for_diagnostic();
708
709 let hi = self.prev_token.span.hi();
711 _ = self.eat(exp!(Comma)) || self.eat(exp!(Colon)) || self.eat(exp!(Star));
712 let suggestion_span = self.prev_token.span.with_lo(hi);
713
714 let length = match self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct) {
717 Ok(length) => length,
718 Err(e) => {
719 e.cancel();
720 self.restore_snapshot(snapshot);
721 return Err(err);
722 }
723 };
724
725 if let Err(e) = self.expect(exp!(CloseBracket)) {
726 e.cancel();
727 self.restore_snapshot(snapshot);
728 return Err(err);
729 }
730
731 err.span_suggestion_verbose(
732 suggestion_span,
733 "you might have meant to use `;` as the separator",
734 ";",
735 Applicability::MaybeIncorrect,
736 );
737 err.emit();
738 Ok(TyKind::Array(elt_ty, length))
739 }
740
741 fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
742 let and_span = self.prev_token.span;
743 let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
744 let (pinned, mut mutbl) = self.parse_pin_and_mut();
745 if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
746 if !self.look_ahead(1, |t| t.is_like_plus()) {
752 let lifetime_span = self.token.span;
753 let span = and_span.to(lifetime_span);
754
755 let (suggest_lifetime, snippet) =
756 if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
757 (Some(span), lifetime_src)
758 } else {
759 (None, String::new())
760 };
761 self.dcx().emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
762
763 opt_lifetime = Some(self.expect_lifetime());
764 }
765 } else if self.token.is_keyword(kw::Dyn)
766 && mutbl == Mutability::Not
767 && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
768 {
769 let span = and_span.to(self.look_ahead(1, |t| t.span));
771 self.dcx().emit_err(DynAfterMut { span });
772
773 mutbl = Mutability::Mut;
775 let (dyn_tok, dyn_tok_sp) = (self.token, self.token_spacing);
776 self.bump();
777 self.bump_with((dyn_tok, dyn_tok_sp));
778 }
779 let ty = self.parse_ty_no_plus()?;
780 Ok(match pinned {
781 Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
782 Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
783 })
784 }
785
786 pub(crate) fn parse_pin_and_mut(&mut self) -> (Pinnedness, Mutability) {
790 if self.token.is_ident_named(sym::pin) && self.look_ahead(1, Token::is_mutability) {
791 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
792 assert!(self.eat_keyword(exp!(Pin)));
793 let mutbl = self.parse_const_or_mut().unwrap();
794 (Pinnedness::Pinned, mutbl)
795 } else {
796 (Pinnedness::Not, self.parse_mutability())
797 }
798 }
799
800 fn parse_typeof_ty(&mut self, lo: Span) -> PResult<'a, TyKind> {
803 self.expect(exp!(OpenParen))?;
804 let _expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?;
805 self.expect(exp!(CloseParen))?;
806 let span = lo.to(self.prev_token.span);
807 let guar = self
808 .dcx()
809 .struct_span_err(span, "`typeof` is a reserved keyword but unimplemented")
810 .with_note("consider replacing `typeof(...)` with an actual type")
811 .with_code(E0516)
812 .emit();
813 Ok(TyKind::Err(guar))
814 }
815
816 fn parse_ty_fn_ptr(
826 &mut self,
827 lo: Span,
828 mut params: ThinVec<GenericParam>,
829 param_insertion_point: Option<Span>,
830 recover_return_sign: RecoverReturnSign,
831 ) -> PResult<'a, TyKind> {
832 let inherited_vis = rustc_ast::Visibility {
833 span: rustc_span::DUMMY_SP,
834 kind: rustc_ast::VisibilityKind::Inherited,
835 tokens: None,
836 };
837 let span_start = self.token.span;
838 let ast::FnHeader { ext, safety, .. } = self.parse_fn_front_matter(
839 &inherited_vis,
840 Case::Sensitive,
841 FrontMatterParsingMode::FunctionPtrType,
842 )?;
843 if self.may_recover() && self.token == TokenKind::Lt {
844 self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
845 }
846 let mode = crate::parser::item::FnParseMode {
847 req_name: |_, _| false,
848 context: FnContext::Free,
849 req_body: false,
850 };
851 let decl = self.parse_fn_decl(&mode, AllowPlus::No, recover_return_sign)?;
852
853 let decl_span = span_start.to(self.prev_token.span);
854 Ok(TyKind::FnPtr(Box::new(FnPtrTy {
855 ext,
856 safety,
857 generic_params: params,
858 decl,
859 decl_span,
860 })))
861 }
862
863 fn recover_fn_ptr_with_generics(
865 &mut self,
866 lo: Span,
867 params: &mut ThinVec<GenericParam>,
868 param_insertion_point: Option<Span>,
869 ) -> PResult<'a, ()> {
870 let generics = self.parse_generics()?;
871 let arity = generics.params.len();
872
873 let mut lifetimes: ThinVec<_> = generics
874 .params
875 .into_iter()
876 .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
877 .collect();
878
879 let sugg = if !lifetimes.is_empty() {
880 let snippet =
881 lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
882
883 let (left, snippet) = if let Some(span) = param_insertion_point {
884 (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
885 } else {
886 (lo.shrink_to_lo(), format!("for<{snippet}> "))
887 };
888
889 Some(FnPtrWithGenericsSugg {
890 left,
891 snippet,
892 right: generics.span,
893 arity,
894 for_param_list_exists: param_insertion_point.is_some(),
895 })
896 } else {
897 None
898 };
899
900 self.dcx().emit_err(FnPtrWithGenerics { span: generics.span, sugg });
901 params.append(&mut lifetimes);
902 Ok(())
903 }
904
905 fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
907 if self.token.is_lifetime() {
908 self.look_ahead(1, |t| {
909 if let token::Ident(sym, _) = t.kind {
910 self.dcx().emit_err(errors::MissingPlusBounds {
913 span: self.token.span,
914 hi: self.token.span.shrink_to_hi(),
915 sym,
916 });
917 }
918 })
919 }
920
921 let bounds = self.parse_generic_bounds()?;
923
924 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
925
926 Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
927 }
928
929 fn parse_use_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
936 self.expect_lt()?;
937 let (args, _, _) = self.parse_seq_to_before_tokens(
938 &[exp!(Gt)],
939 &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr],
940 SeqSep::trailing_allowed(exp!(Comma)),
941 |self_| {
942 if self_.check_keyword(exp!(SelfUpper)) {
943 self_.bump();
944 Ok(PreciseCapturingArg::Arg(
945 ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
946 DUMMY_NODE_ID,
947 ))
948 } else if self_.check_ident() {
949 Ok(PreciseCapturingArg::Arg(
950 ast::Path::from_ident(self_.parse_ident()?),
951 DUMMY_NODE_ID,
952 ))
953 } else if self_.check_lifetime() {
954 Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
955 } else {
956 self_.unexpected_any()
957 }
958 },
959 )?;
960 self.expect_gt()?;
961
962 if let ast::Parens::Yes = parens {
963 self.expect(exp!(CloseParen))?;
964 self.report_parenthesized_bound(lo, self.prev_token.span, "precise capturing lists");
965 }
966
967 Ok(GenericBound::Use(args, lo.to(self.prev_token.span)))
968 }
969
970 fn is_explicit_dyn_type(&mut self) -> bool {
972 self.check_keyword(exp!(Dyn))
973 && (self.token_uninterpolated_span().at_least_rust_2018()
974 || self.look_ahead(1, |&t| can_begin_dyn_bound_in_edition_2015(t)))
975 }
976
977 fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
981 self.bump(); let bounds = self.parse_generic_bounds()?;
985 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
986
987 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn))
988 }
989
990 fn parse_path_start_ty(
997 &mut self,
998 lo: Span,
999 allow_plus: AllowPlus,
1000 ty_generics: Option<&Generics>,
1001 ) -> PResult<'a, TyKind> {
1002 let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
1004 if self.eat(exp!(Bang)) {
1005 Ok(TyKind::MacCall(Box::new(MacCall { path, args: self.parse_delim_args()? })))
1007 } else if allow_plus == AllowPlus::Yes && self.check_plus() {
1008 self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true, ast::Parens::No)
1010 } else {
1011 Ok(TyKind::Path(None, path))
1013 }
1014 }
1015
1016 pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
1017 self.parse_generic_bounds_common(AllowPlus::Yes)
1018 }
1019
1020 fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
1025 let mut bounds = Vec::new();
1026
1027 while self.can_begin_bound()
1033 || (self.may_recover()
1034 && (self.token.can_begin_type()
1035 || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
1036 {
1037 if self.token.is_keyword(kw::Dyn) {
1038 self.bump();
1040 self.dcx().emit_err(InvalidDynKeyword {
1041 span: self.prev_token.span,
1042 suggestion: self.prev_token.span.until(self.token.span),
1043 });
1044 }
1045 bounds.push(self.parse_generic_bound()?);
1046 if allow_plus == AllowPlus::No || !self.eat_plus() {
1047 break;
1048 }
1049 }
1050
1051 Ok(bounds)
1052 }
1053
1054 fn can_begin_bound(&mut self) -> bool {
1056 self.check_path()
1057 || self.check_lifetime()
1058 || self.check(exp!(Bang))
1059 || self.check(exp!(Question))
1060 || self.check(exp!(Tilde))
1061 || self.check_keyword(exp!(For))
1062 || self.check(exp!(OpenParen))
1063 || self.can_begin_maybe_const_bound()
1064 || self.check_keyword(exp!(Const))
1065 || self.check_keyword(exp!(Async))
1066 || self.check_keyword(exp!(Use))
1067 }
1068
1069 fn can_begin_maybe_const_bound(&mut self) -> bool {
1070 self.check(exp!(OpenBracket))
1071 && self.look_ahead(1, |t| t.is_keyword(kw::Const))
1072 && self.look_ahead(2, |t| *t == token::CloseBracket)
1073 }
1074
1075 fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
1081 let leading_token = self.prev_token;
1082 let lo = self.token.span;
1083
1084 let parens = if self.eat(exp!(OpenParen)) { ast::Parens::Yes } else { ast::Parens::No };
1090
1091 if self.token.is_lifetime() {
1092 self.parse_lifetime_bound(lo, parens)
1093 } else if self.eat_keyword(exp!(Use)) {
1094 self.parse_use_bound(lo, parens)
1095 } else {
1096 self.parse_trait_bound(lo, parens, &leading_token)
1097 }
1098 }
1099
1100 fn parse_lifetime_bound(&mut self, lo: Span, parens: ast::Parens) -> PResult<'a, GenericBound> {
1106 let lt = self.expect_lifetime();
1107
1108 if let ast::Parens::Yes = parens {
1109 self.expect(exp!(CloseParen))?;
1110 self.report_parenthesized_bound(lo, self.prev_token.span, "lifetime bounds");
1111 }
1112
1113 Ok(GenericBound::Outlives(lt))
1114 }
1115
1116 fn report_parenthesized_bound(&self, lo: Span, hi: Span, kind: &str) -> ErrorGuaranteed {
1117 let mut diag =
1118 self.dcx().struct_span_err(lo.to(hi), format!("{kind} may not be parenthesized"));
1119 diag.multipart_suggestion(
1120 "remove the parentheses",
1121 vec![(lo, String::new()), (hi, String::new())],
1122 Applicability::MachineApplicable,
1123 );
1124 diag.emit()
1125 }
1126
1127 fn error_lt_bound_with_modifiers(
1129 &self,
1130 modifiers: TraitBoundModifiers,
1131 binder_span: Option<Span>,
1132 ) -> ErrorGuaranteed {
1133 let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
1134
1135 match constness {
1136 BoundConstness::Never => {}
1137 BoundConstness::Always(span) | BoundConstness::Maybe(span) => {
1138 return self
1139 .dcx()
1140 .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() });
1141 }
1142 }
1143
1144 match polarity {
1145 BoundPolarity::Positive => {}
1146 BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
1147 return self
1148 .dcx()
1149 .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() });
1150 }
1151 }
1152
1153 match asyncness {
1154 BoundAsyncness::Normal => {}
1155 BoundAsyncness::Async(span) => {
1156 return self
1157 .dcx()
1158 .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() });
1159 }
1160 }
1161
1162 if let Some(span) = binder_span {
1163 return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" });
1164 }
1165
1166 unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
1167 }
1168
1169 fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
1181 let modifier_lo = self.token.span;
1182 let constness = self.parse_bound_constness()?;
1183
1184 let asyncness = if self.token_uninterpolated_span().at_least_rust_2018()
1185 && self.eat_keyword(exp!(Async))
1186 {
1187 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1188 BoundAsyncness::Async(self.prev_token.span)
1189 } else if self.may_recover()
1190 && self.token_uninterpolated_span().is_rust_2015()
1191 && self.is_kw_followed_by_ident(kw::Async)
1192 {
1193 self.bump(); self.dcx().emit_err(errors::AsyncBoundModifierIn2015 {
1195 span: self.prev_token.span,
1196 help: HelpUseLatestEdition::new(),
1197 });
1198 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1199 BoundAsyncness::Async(self.prev_token.span)
1200 } else {
1201 BoundAsyncness::Normal
1202 };
1203 let modifier_hi = self.prev_token.span;
1204
1205 let polarity = if self.eat(exp!(Question)) {
1206 BoundPolarity::Maybe(self.prev_token.span)
1207 } else if self.eat(exp!(Bang)) {
1208 self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
1209 BoundPolarity::Negative(self.prev_token.span)
1210 } else {
1211 BoundPolarity::Positive
1212 };
1213
1214 match polarity {
1216 BoundPolarity::Positive => {
1217 }
1219 BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1220 match (asyncness, constness) {
1221 (BoundAsyncness::Normal, BoundConstness::Never) => {
1222 }
1224 (_, _) => {
1225 let constness = constness.as_str();
1226 let asyncness = asyncness.as_str();
1227 let glue =
1228 if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
1229 let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
1230 self.dcx().emit_err(errors::PolarityAndModifiers {
1231 polarity_span,
1232 polarity: polarity.as_str(),
1233 modifiers_span: modifier_lo.to(modifier_hi),
1234 modifiers_concatenated,
1235 });
1236 }
1237 }
1238 }
1239 }
1240
1241 Ok(TraitBoundModifiers { constness, asyncness, polarity })
1242 }
1243
1244 pub fn parse_bound_constness(&mut self) -> PResult<'a, BoundConstness> {
1245 Ok(if self.eat(exp!(Tilde)) {
1248 let tilde = self.prev_token.span;
1249 self.expect_keyword(exp!(Const))?;
1250 let span = tilde.to(self.prev_token.span);
1251 self.psess.gated_spans.gate(sym::const_trait_impl, span);
1252 BoundConstness::Maybe(span)
1253 } else if self.can_begin_maybe_const_bound() {
1254 let start = self.token.span;
1255 self.bump();
1256 self.expect_keyword(exp!(Const)).unwrap();
1257 self.bump();
1258 let span = start.to(self.prev_token.span);
1259 self.psess.gated_spans.gate(sym::const_trait_impl, span);
1260 BoundConstness::Maybe(span)
1261 } else if self.eat_keyword(exp!(Const)) {
1262 self.psess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span);
1263 BoundConstness::Always(self.prev_token.span)
1264 } else {
1265 BoundConstness::Never
1266 })
1267 }
1268
1269 fn parse_trait_bound(
1278 &mut self,
1279 lo: Span,
1280 parens: ast::Parens,
1281 leading_token: &Token,
1282 ) -> PResult<'a, GenericBound> {
1283 let (mut bound_vars, binder_span) = self.parse_higher_ranked_binder()?;
1284
1285 let modifiers_lo = self.token.span;
1286 let modifiers = self.parse_trait_bound_modifiers()?;
1287 let modifiers_span = modifiers_lo.to(self.prev_token.span);
1288
1289 if let Some(binder_span) = binder_span {
1290 match modifiers.polarity {
1291 BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1292 self.dcx().emit_err(errors::BinderAndPolarity {
1293 binder_span,
1294 polarity_span,
1295 polarity: modifiers.polarity.as_str(),
1296 });
1297 }
1298 BoundPolarity::Positive => {}
1299 }
1300 }
1301
1302 if self.token.is_lifetime() {
1305 let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
1306 return self.parse_lifetime_bound(lo, parens);
1307 }
1308
1309 if let (more_bound_vars, Some(binder_span)) = self.parse_higher_ranked_binder()? {
1310 bound_vars.extend(more_bound_vars);
1311 self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
1312 }
1313
1314 let mut path = if self.token.is_keyword(kw::Fn)
1315 && self.look_ahead(1, |t| *t == TokenKind::OpenParen)
1316 && let Some(path) = self.recover_path_from_fn()
1317 {
1318 path
1319 } else if !self.token.is_path_start() && self.token.can_begin_type() {
1320 let ty = self.parse_ty_no_plus()?;
1321 let mut err = self.dcx().struct_span_err(ty.span, "expected a trait, found type");
1323
1324 let path = if self.may_recover() {
1329 let (span, message, sugg, path, applicability) = match &ty.kind {
1330 TyKind::Ptr(..) | TyKind::Ref(..)
1331 if let TyKind::Path(_, path) = &ty.peel_refs().kind =>
1332 {
1333 (
1334 ty.span.until(path.span),
1335 "consider removing the indirection",
1336 "",
1337 path,
1338 Applicability::MaybeIncorrect,
1339 )
1340 }
1341 TyKind::ImplTrait(_, bounds)
1342 if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
1343 {
1344 (
1345 ty.span.until(tr.span),
1346 "use the trait bounds directly",
1347 "",
1348 &tr.trait_ref.path,
1349 Applicability::MachineApplicable,
1350 )
1351 }
1352 _ => return Err(err),
1353 };
1354
1355 err.span_suggestion_verbose(span, message, sugg, applicability);
1356
1357 path.clone()
1358 } else {
1359 return Err(err);
1360 };
1361
1362 err.emit();
1363
1364 path
1365 } else {
1366 self.parse_path(PathStyle::Type)?
1367 };
1368
1369 if self.may_recover() && self.token == TokenKind::OpenParen {
1370 self.recover_fn_trait_with_lifetime_params(&mut path, &mut bound_vars)?;
1371 }
1372
1373 if let ast::Parens::Yes = parens {
1374 if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1377 let bounds = vec![];
1378 self.parse_remaining_bounds(bounds, true)?;
1379 self.expect(exp!(CloseParen))?;
1380 self.dcx().emit_err(errors::IncorrectParensTraitBounds {
1381 span: vec![lo, self.prev_token.span],
1382 sugg: errors::IncorrectParensTraitBoundsSugg {
1383 wrong_span: leading_token.span.shrink_to_hi().to(lo),
1384 new_span: leading_token.span.shrink_to_lo(),
1385 },
1386 });
1387 } else {
1388 self.expect(exp!(CloseParen))?;
1389 }
1390 }
1391
1392 let poly_trait =
1393 PolyTraitRef::new(bound_vars, path, modifiers, lo.to(self.prev_token.span), parens);
1394 Ok(GenericBound::Trait(poly_trait))
1395 }
1396
1397 fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1399 let fn_token_span = self.token.span;
1400 self.bump();
1401 let args_lo = self.token.span;
1402 let snapshot = self.create_snapshot_for_diagnostic();
1403 let mode =
1404 FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
1405 match self.parse_fn_decl(&mode, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1406 Ok(decl) => {
1407 self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1408 Some(ast::Path {
1409 span: fn_token_span.to(self.prev_token.span),
1410 segments: thin_vec![ast::PathSegment {
1411 ident: Ident::new(sym::Fn, fn_token_span),
1412 id: DUMMY_NODE_ID,
1413 args: Some(Box::new(ast::GenericArgs::Parenthesized(
1414 ast::ParenthesizedArgs {
1415 span: args_lo.to(self.prev_token.span),
1416 inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
1417 inputs_span: args_lo.until(decl.output.span()),
1418 output: decl.output.clone(),
1419 }
1420 ))),
1421 }],
1422 tokens: None,
1423 })
1424 }
1425 Err(diag) => {
1426 diag.cancel();
1427 self.restore_snapshot(snapshot);
1428 None
1429 }
1430 }
1431 }
1432
1433 pub(super) fn parse_higher_ranked_binder(
1439 &mut self,
1440 ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
1441 if self.eat_keyword(exp!(For)) {
1442 let lo = self.token.span;
1443 self.expect_lt()?;
1444 let params = self.parse_generic_params()?;
1445 self.expect_gt()?;
1446 Ok((params, Some(lo.to(self.prev_token.span))))
1449 } else {
1450 Ok((ThinVec::new(), None))
1451 }
1452 }
1453
1454 fn recover_fn_trait_with_lifetime_params(
1458 &mut self,
1459 fn_path: &mut ast::Path,
1460 lifetime_defs: &mut ThinVec<GenericParam>,
1461 ) -> PResult<'a, ()> {
1462 let fn_path_segment = fn_path.segments.last_mut().unwrap();
1463 let generic_args = if let Some(p_args) = &fn_path_segment.args {
1464 *p_args.clone()
1465 } else {
1466 return Ok(());
1469 };
1470 let lifetimes =
1471 if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1472 &generic_args
1473 {
1474 args.into_iter()
1475 .filter_map(|arg| {
1476 if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1477 && let ast::GenericArg::Lifetime(lifetime) = generic_arg
1478 {
1479 Some(lifetime)
1480 } else {
1481 None
1482 }
1483 })
1484 .collect()
1485 } else {
1486 Vec::new()
1487 };
1488 if lifetimes.is_empty() {
1490 return Ok(());
1491 }
1492
1493 let inputs_lo = self.token.span;
1495 let mode =
1496 FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false };
1497 let inputs: ThinVec<_> =
1498 self.parse_fn_params(&mode)?.into_iter().map(|input| input.ty).collect();
1499 let inputs_span = inputs_lo.to(self.prev_token.span);
1500 let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
1501 let args = ast::ParenthesizedArgs {
1502 span: fn_path_segment.span().to(self.prev_token.span),
1503 inputs,
1504 inputs_span,
1505 output,
1506 }
1507 .into();
1508 *fn_path_segment = ast::PathSegment {
1509 ident: fn_path_segment.ident,
1510 args: Some(args),
1511 id: ast::DUMMY_NODE_ID,
1512 };
1513
1514 let mut generic_params = lifetimes
1516 .iter()
1517 .map(|lt| GenericParam {
1518 id: lt.id,
1519 ident: lt.ident,
1520 attrs: ast::AttrVec::new(),
1521 bounds: Vec::new(),
1522 is_placeholder: false,
1523 kind: ast::GenericParamKind::Lifetime,
1524 colon_span: None,
1525 })
1526 .collect::<ThinVec<GenericParam>>();
1527 lifetime_defs.append(&mut generic_params);
1528
1529 let generic_args_span = generic_args.span();
1530 let snippet = format!(
1531 "for<{}> ",
1532 lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1533 );
1534 let before_fn_path = fn_path.span.shrink_to_lo();
1535 self.dcx()
1536 .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
1537 .with_multipart_suggestion(
1538 "consider using a higher-ranked trait bound instead",
1539 vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1540 Applicability::MaybeIncorrect,
1541 )
1542 .emit();
1543 Ok(())
1544 }
1545
1546 pub(super) fn check_lifetime(&mut self) -> bool {
1547 self.expected_token_types.insert(TokenType::Lifetime);
1548 self.token.is_lifetime()
1549 }
1550
1551 pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1553 if let Some((ident, is_raw)) = self.token.lifetime() {
1554 if matches!(is_raw, IdentIsRaw::No)
1555 && ident.without_first_quote().is_reserved_lifetime()
1556 {
1557 self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
1558 }
1559
1560 self.bump();
1561 Lifetime { ident, id: ast::DUMMY_NODE_ID }
1562 } else {
1563 self.dcx().span_bug(self.token.span, "not a lifetime")
1564 }
1565 }
1566
1567 pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> Box<Ty> {
1568 Box::new(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1569 }
1570}