1use rustc_ast::ptr::P;
2use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind};
3use rustc_ast::util::case::Case;
4use rustc_ast::{
5 self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy,
6 GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
7 Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
8 TyKind, UnsafeBinderTy,
9};
10use rustc_data_structures::stack::ensure_sufficient_stack;
11use rustc_errors::{Applicability, Diag, PResult};
12use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
13use thin_vec::{ThinVec, thin_vec};
14
15use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
16use crate::errors::{
17 self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
18 FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword,
19 LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
20 ReturnTypesUseThinArrow,
21};
22use crate::parser::item::FrontMatterParsingMode;
23use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
24
25#[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_continue_type_after_non_fn_ident(t: &Token) -> bool {
91 t == &token::PathSep || t == &token::Lt || t == &token::Shl
92}
93
94fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
95 t.is_path_start()
100 || t.is_lifetime()
101 || t == &TokenKind::Question
102 || t.is_keyword(kw::For)
103 || t == &TokenKind::OpenParen
104}
105
106impl<'a> Parser<'a> {
107 pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
109 ensure_sufficient_stack(|| {
111 self.parse_ty_common(
112 AllowPlus::Yes,
113 AllowCVariadic::No,
114 RecoverQPath::Yes,
115 RecoverReturnSign::Yes,
116 None,
117 RecoverQuestionMark::Yes,
118 )
119 })
120 }
121
122 pub(super) fn parse_ty_with_generics_recovery(
123 &mut self,
124 ty_params: &Generics,
125 ) -> PResult<'a, P<Ty>> {
126 self.parse_ty_common(
127 AllowPlus::Yes,
128 AllowCVariadic::No,
129 RecoverQPath::Yes,
130 RecoverReturnSign::Yes,
131 Some(ty_params),
132 RecoverQuestionMark::Yes,
133 )
134 }
135
136 pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
140 self.parse_ty_common(
141 AllowPlus::Yes,
142 AllowCVariadic::Yes,
143 RecoverQPath::Yes,
144 RecoverReturnSign::Yes,
145 None,
146 RecoverQuestionMark::Yes,
147 )
148 }
149
150 pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
157 self.parse_ty_common(
158 AllowPlus::No,
159 AllowCVariadic::No,
160 RecoverQPath::Yes,
161 RecoverReturnSign::Yes,
162 None,
163 RecoverQuestionMark::Yes,
164 )
165 }
166
167 pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
170 self.parse_ty_common(
171 AllowPlus::No,
172 AllowCVariadic::No,
173 RecoverQPath::Yes,
174 RecoverReturnSign::Yes,
175 None,
176 RecoverQuestionMark::No,
177 )
178 }
179
180 pub(super) fn parse_ty_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
181 self.parse_ty_common(
182 AllowPlus::Yes,
183 AllowCVariadic::No,
184 RecoverQPath::Yes,
185 RecoverReturnSign::Yes,
186 None,
187 RecoverQuestionMark::No,
188 )
189 }
190
191 pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
194 self.parse_ty_common(
195 AllowPlus::Yes,
196 AllowCVariadic::No,
197 RecoverQPath::Yes,
198 RecoverReturnSign::OnlyFatArrow,
199 None,
200 RecoverQuestionMark::Yes,
201 )
202 }
203
204 pub(super) fn parse_ret_ty(
206 &mut self,
207 allow_plus: AllowPlus,
208 recover_qpath: RecoverQPath,
209 recover_return_sign: RecoverReturnSign,
210 ) -> PResult<'a, FnRetTy> {
211 let lo = self.prev_token.span;
212 Ok(if self.eat(exp!(RArrow)) {
213 let ty = self.parse_ty_common(
215 allow_plus,
216 AllowCVariadic::No,
217 recover_qpath,
218 recover_return_sign,
219 None,
220 RecoverQuestionMark::Yes,
221 )?;
222 FnRetTy::Ty(ty)
223 } else if recover_return_sign.can_recover(&self.token.kind) {
224 self.bump();
227 self.dcx().emit_err(ReturnTypesUseThinArrow {
228 span: self.prev_token.span,
229 suggestion: lo.between(self.token.span),
230 });
231 let ty = self.parse_ty_common(
232 allow_plus,
233 AllowCVariadic::No,
234 recover_qpath,
235 recover_return_sign,
236 None,
237 RecoverQuestionMark::Yes,
238 )?;
239 FnRetTy::Ty(ty)
240 } else {
241 FnRetTy::Default(self.prev_token.span.shrink_to_hi())
242 })
243 }
244
245 fn parse_ty_common(
246 &mut self,
247 allow_plus: AllowPlus,
248 allow_c_variadic: AllowCVariadic,
249 recover_qpath: RecoverQPath,
250 recover_return_sign: RecoverReturnSign,
251 ty_generics: Option<&Generics>,
252 recover_question_mark: RecoverQuestionMark,
253 ) -> PResult<'a, P<Ty>> {
254 let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
255 maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
256
257 if let Some(ty) = self.eat_metavar_seq_with_matcher(
258 |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }),
259 |this| this.parse_ty_no_question_mark_recover(),
260 ) {
261 return Ok(ty);
262 }
263
264 let lo = self.token.span;
265 let mut impl_dyn_multi = false;
266 let kind = if self.check(exp!(OpenParen)) {
267 self.parse_ty_tuple_or_parens(lo, allow_plus)?
268 } else if self.eat(exp!(Bang)) {
269 TyKind::Never
271 } else if self.eat(exp!(Star)) {
272 self.parse_ty_ptr()?
273 } else if self.eat(exp!(OpenBracket)) {
274 self.parse_array_or_slice_ty()?
275 } else if self.check(exp!(And)) || self.check(exp!(AndAnd)) {
276 self.expect_and()?;
278 self.parse_borrowed_pointee()?
279 } else if self.eat_keyword_noexpect(kw::Typeof) {
280 self.parse_typeof_ty()?
281 } else if self.eat_keyword(exp!(Underscore)) {
282 TyKind::Infer
284 } else if self.check_fn_front_matter(false, Case::Sensitive) {
285 self.parse_ty_fn_ptr(lo, ThinVec::new(), None, recover_return_sign)?
287 } else if self.check_keyword(exp!(For)) {
288 let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?;
292 if self.check_fn_front_matter(false, Case::Sensitive) {
293 self.parse_ty_fn_ptr(
294 lo,
295 lifetime_defs,
296 Some(self.prev_token.span.shrink_to_lo()),
297 recover_return_sign,
298 )?
299 } else {
300 if self.may_recover()
302 && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn))
303 {
304 let kw = self.prev_token.ident().unwrap().0;
305 let removal_span = kw.span.with_hi(self.token.span.lo());
306 let path = self.parse_path(PathStyle::Type)?;
307 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
308 let kind = self.parse_remaining_bounds_path(
309 lifetime_defs,
310 path,
311 lo,
312 parse_plus,
313 ast::Parens::No,
314 )?;
315 let err = self.dcx().create_err(errors::TransposeDynOrImpl {
316 span: kw.span,
317 kw: kw.name.as_str(),
318 sugg: errors::TransposeDynOrImplSugg {
319 removal_span,
320 insertion_span: lo.shrink_to_lo(),
321 kw: kw.name.as_str(),
322 },
323 });
324
325 let kind = match (kind, kw.name) {
328 (TyKind::TraitObject(bounds, _), kw::Dyn) => {
329 TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
330 }
331 (TyKind::TraitObject(bounds, _), kw::Impl) => {
332 TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
333 }
334 _ => return Err(err),
335 };
336 err.emit();
337 kind
338 } else {
339 let path = self.parse_path(PathStyle::Type)?;
340 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
341 self.parse_remaining_bounds_path(
342 lifetime_defs,
343 path,
344 lo,
345 parse_plus,
346 ast::Parens::No,
347 )?
348 }
349 }
350 } else if self.eat_keyword(exp!(Impl)) {
351 self.parse_impl_ty(&mut impl_dyn_multi)?
352 } else if self.is_explicit_dyn_type() {
353 self.parse_dyn_ty(&mut impl_dyn_multi)?
354 } else if self.eat_lt() {
355 let (qself, path) = self.parse_qpath(PathStyle::Type)?;
357 TyKind::Path(Some(qself), path)
358 } else if self.check_path() {
359 self.parse_path_start_ty(lo, allow_plus, ty_generics)?
360 } else if self.can_begin_bound() {
361 self.parse_bare_trait_object(lo, allow_plus)?
362 } else if self.eat(exp!(DotDotDot)) {
363 match allow_c_variadic {
364 AllowCVariadic::Yes => TyKind::CVarArgs,
365 AllowCVariadic::No => {
366 let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
370 TyKind::Err(guar)
371 }
372 }
373 } else if self.check_keyword(exp!(Unsafe))
374 && self.look_ahead(1, |tok| tok.kind == token::Lt)
375 {
376 self.parse_unsafe_binder_ty()?
377 } else {
378 let msg = format!("expected type, found {}", super::token_descr(&self.token));
379 let mut err = self.dcx().struct_span_err(lo, msg);
380 err.span_label(lo, "expected type");
381 return Err(err);
382 };
383
384 let span = lo.to(self.prev_token.span);
385 let mut ty = self.mk_ty(span, kind);
386
387 match allow_plus {
389 AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
390 AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
391 }
392 if let RecoverQuestionMark::Yes = recover_question_mark {
393 ty = self.maybe_recover_from_question_mark(ty);
394 }
395 if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
396 }
397
398 fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
399 let lo = self.token.span;
400 assert!(self.eat_keyword(exp!(Unsafe)));
401 self.expect_lt()?;
402 let generic_params = self.parse_generic_params()?;
403 self.expect_gt()?;
404 let inner_ty = self.parse_ty()?;
405 let span = lo.to(self.prev_token.span);
406 self.psess.gated_spans.gate(sym::unsafe_binders, span);
407
408 Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
409 }
410
411 fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
415 let mut trailing_plus = false;
416 let (ts, trailing) = self.parse_paren_comma_seq(|p| {
417 let ty = p.parse_ty()?;
418 trailing_plus = p.prev_token == TokenKind::Plus;
419 Ok(ty)
420 })?;
421
422 if ts.len() == 1 && matches!(trailing, Trailing::No) {
423 let ty = ts.into_iter().next().unwrap();
424 let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
425 match ty.kind {
426 TyKind::Path(None, path) if maybe_bounds => self.parse_remaining_bounds_path(
428 ThinVec::new(),
429 path,
430 lo,
431 true,
432 ast::Parens::Yes,
433 ),
434 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
438 if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
439 {
440 self.parse_remaining_bounds(bounds, true)
441 }
442 _ => Ok(TyKind::Paren(ty)),
444 }
445 } else {
446 Ok(TyKind::Tup(ts))
447 }
448 }
449
450 fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
451 if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) {
453 if self.psess.edition.at_least_rust_2021() {
457 let lt = self.expect_lifetime();
458 let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime");
459 err.span_label(lo, "expected type");
460 return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) {
461 Ok(ref_ty) => ref_ty,
462 Err(err) => TyKind::Err(err.emit()),
463 });
464 }
465
466 self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime {
467 span: lo,
468 suggestion: lo.shrink_to_hi(),
469 });
470 }
471 Ok(TyKind::TraitObject(
472 self.parse_generic_bounds_common(allow_plus)?,
473 TraitObjectSyntax::None,
474 ))
475 }
476
477 fn maybe_recover_ref_ty_no_leading_ampersand<'cx>(
478 &mut self,
479 lt: Lifetime,
480 lo: Span,
481 mut err: Diag<'cx>,
482 ) -> Result<TyKind, Diag<'cx>> {
483 if !self.may_recover() {
484 return Err(err);
485 }
486 let snapshot = self.create_snapshot_for_diagnostic();
487 let mutbl = self.parse_mutability();
488 match self.parse_ty_no_plus() {
489 Ok(ty) => {
490 err.span_suggestion_verbose(
491 lo.shrink_to_lo(),
492 "you might have meant to write a reference type here",
493 "&",
494 Applicability::MaybeIncorrect,
495 );
496 err.emit();
497 Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl }))
498 }
499 Err(diag) => {
500 diag.cancel();
501 self.restore_snapshot(snapshot);
502 Err(err)
503 }
504 }
505 }
506
507 fn parse_remaining_bounds_path(
508 &mut self,
509 generic_params: ThinVec<GenericParam>,
510 path: ast::Path,
511 lo: Span,
512 parse_plus: bool,
513 parens: ast::Parens,
514 ) -> PResult<'a, TyKind> {
515 let poly_trait_ref = PolyTraitRef::new(
516 generic_params,
517 path,
518 TraitBoundModifiers::NONE,
519 lo.to(self.prev_token.span),
520 parens,
521 );
522 let bounds = vec![GenericBound::Trait(poly_trait_ref)];
523 self.parse_remaining_bounds(bounds, parse_plus)
524 }
525
526 fn parse_remaining_bounds(
528 &mut self,
529 mut bounds: GenericBounds,
530 plus: bool,
531 ) -> PResult<'a, TyKind> {
532 if plus {
533 self.eat_plus(); bounds.append(&mut self.parse_generic_bounds()?);
535 }
536 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
537 }
538
539 fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
541 let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
542 let span = self.prev_token.span;
543 self.dcx().emit_err(ExpectedMutOrConstInRawPointerType {
544 span,
545 after_asterisk: span.shrink_to_hi(),
546 });
547 Mutability::Not
548 });
549 let ty = self.parse_ty_no_plus()?;
550 Ok(TyKind::Ptr(MutTy { ty, mutbl }))
551 }
552
553 fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
556 let elt_ty = match self.parse_ty() {
557 Ok(ty) => ty,
558 Err(err)
559 if self.look_ahead(1, |t| *t == token::CloseBracket)
560 | self.look_ahead(1, |t| *t == token::Semi) =>
561 {
562 self.bump();
564 let guar = err.emit();
565 self.mk_ty(self.prev_token.span, TyKind::Err(guar))
566 }
567 Err(err) => return Err(err),
568 };
569
570 let ty = if self.eat(exp!(Semi)) {
571 let mut length = self.parse_expr_anon_const()?;
572 if let Err(e) = self.expect(exp!(CloseBracket)) {
573 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
575 self.expect(exp!(CloseBracket))?;
576 }
577 TyKind::Array(elt_ty, length)
578 } else {
579 self.expect(exp!(CloseBracket))?;
580 TyKind::Slice(elt_ty)
581 };
582
583 Ok(ty)
584 }
585
586 fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
587 let and_span = self.prev_token.span;
588 let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
589 let (pinned, mut mutbl) = match self.parse_pin_and_mut() {
590 Some(pin_mut) => pin_mut,
591 None => (Pinnedness::Not, self.parse_mutability()),
592 };
593 if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
594 if !self.look_ahead(1, |t| t.is_like_plus()) {
600 let lifetime_span = self.token.span;
601 let span = and_span.to(lifetime_span);
602
603 let (suggest_lifetime, snippet) =
604 if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
605 (Some(span), lifetime_src)
606 } else {
607 (None, String::new())
608 };
609 self.dcx().emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
610
611 opt_lifetime = Some(self.expect_lifetime());
612 }
613 } else if self.token.is_keyword(kw::Dyn)
614 && mutbl == Mutability::Not
615 && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
616 {
617 let span = and_span.to(self.look_ahead(1, |t| t.span));
619 self.dcx().emit_err(DynAfterMut { span });
620
621 mutbl = Mutability::Mut;
623 let (dyn_tok, dyn_tok_sp) = (self.token, self.token_spacing);
624 self.bump();
625 self.bump_with((dyn_tok, dyn_tok_sp));
626 }
627 let ty = self.parse_ty_no_plus()?;
628 Ok(match pinned {
629 Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
630 Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
631 })
632 }
633
634 pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> {
638 if self.token.is_ident_named(sym::pin) {
639 let result = self.look_ahead(1, |token| {
640 if token.is_keyword(kw::Const) {
641 Some((Pinnedness::Pinned, Mutability::Not))
642 } else if token.is_keyword(kw::Mut) {
643 Some((Pinnedness::Pinned, Mutability::Mut))
644 } else {
645 None
646 }
647 });
648 if result.is_some() {
649 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
650 self.bump();
651 self.bump();
652 }
653 result
654 } else {
655 None
656 }
657 }
658
659 fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
662 self.expect(exp!(OpenParen))?;
663 let expr = self.parse_expr_anon_const()?;
664 self.expect(exp!(CloseParen))?;
665 Ok(TyKind::Typeof(expr))
666 }
667
668 fn parse_ty_fn_ptr(
678 &mut self,
679 lo: Span,
680 mut params: ThinVec<GenericParam>,
681 param_insertion_point: Option<Span>,
682 recover_return_sign: RecoverReturnSign,
683 ) -> PResult<'a, TyKind> {
684 let inherited_vis = rustc_ast::Visibility {
685 span: rustc_span::DUMMY_SP,
686 kind: rustc_ast::VisibilityKind::Inherited,
687 tokens: None,
688 };
689 let span_start = self.token.span;
690 let ast::FnHeader { ext, safety, .. } = self.parse_fn_front_matter(
691 &inherited_vis,
692 Case::Sensitive,
693 FrontMatterParsingMode::FunctionPtrType,
694 )?;
695 if self.may_recover() && self.token == TokenKind::Lt {
696 self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
697 }
698 let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
699
700 let decl_span = span_start.to(self.prev_token.span);
701 Ok(TyKind::FnPtr(P(FnPtrTy { ext, safety, generic_params: params, decl, decl_span })))
702 }
703
704 fn recover_fn_ptr_with_generics(
706 &mut self,
707 lo: Span,
708 params: &mut ThinVec<GenericParam>,
709 param_insertion_point: Option<Span>,
710 ) -> PResult<'a, ()> {
711 let generics = self.parse_generics()?;
712 let arity = generics.params.len();
713
714 let mut lifetimes: ThinVec<_> = generics
715 .params
716 .into_iter()
717 .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
718 .collect();
719
720 let sugg = if !lifetimes.is_empty() {
721 let snippet =
722 lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
723
724 let (left, snippet) = if let Some(span) = param_insertion_point {
725 (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
726 } else {
727 (lo.shrink_to_lo(), format!("for<{snippet}> "))
728 };
729
730 Some(FnPtrWithGenericsSugg {
731 left,
732 snippet,
733 right: generics.span,
734 arity,
735 for_param_list_exists: param_insertion_point.is_some(),
736 })
737 } else {
738 None
739 };
740
741 self.dcx().emit_err(FnPtrWithGenerics { span: generics.span, sugg });
742 params.append(&mut lifetimes);
743 Ok(())
744 }
745
746 fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
748 if self.token.is_lifetime() {
749 self.look_ahead(1, |t| {
750 if let token::Ident(sym, _) = t.kind {
751 self.dcx().emit_err(errors::MissingPlusBounds {
754 span: self.token.span,
755 hi: self.token.span.shrink_to_hi(),
756 sym,
757 });
758 }
759 })
760 }
761
762 let bounds = self.parse_generic_bounds()?;
764
765 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
766
767 Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
768 }
769
770 fn parse_precise_capturing_args(
771 &mut self,
772 ) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
773 let lo = self.token.span;
774 self.expect_lt()?;
775 let (args, _, _) = self.parse_seq_to_before_tokens(
776 &[exp!(Gt)],
777 &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr],
778 SeqSep::trailing_allowed(exp!(Comma)),
779 |self_| {
780 if self_.check_keyword(exp!(SelfUpper)) {
781 self_.bump();
782 Ok(PreciseCapturingArg::Arg(
783 ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
784 DUMMY_NODE_ID,
785 ))
786 } else if self_.check_ident() {
787 Ok(PreciseCapturingArg::Arg(
788 ast::Path::from_ident(self_.parse_ident()?),
789 DUMMY_NODE_ID,
790 ))
791 } else if self_.check_lifetime() {
792 Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
793 } else {
794 self_.unexpected_any()
795 }
796 },
797 )?;
798 self.expect_gt()?;
799 Ok((args, lo.to(self.prev_token.span)))
800 }
801
802 fn is_explicit_dyn_type(&mut self) -> bool {
804 self.check_keyword(exp!(Dyn))
805 && (self.token_uninterpolated_span().at_least_rust_2018()
806 || self.look_ahead(1, |t| {
807 (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star)
808 && !can_continue_type_after_non_fn_ident(t)
809 }))
810 }
811
812 fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
816 self.bump(); let syntax = TraitObjectSyntax::Dyn;
820
821 let bounds = self.parse_generic_bounds()?;
823 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
824 Ok(TyKind::TraitObject(bounds, syntax))
825 }
826
827 fn parse_path_start_ty(
834 &mut self,
835 lo: Span,
836 allow_plus: AllowPlus,
837 ty_generics: Option<&Generics>,
838 ) -> PResult<'a, TyKind> {
839 let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
841 if self.eat(exp!(Bang)) {
842 Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
844 } else if allow_plus == AllowPlus::Yes && self.check_plus() {
845 self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true, ast::Parens::No)
847 } else {
848 Ok(TyKind::Path(None, path))
850 }
851 }
852
853 pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
854 self.parse_generic_bounds_common(AllowPlus::Yes)
855 }
856
857 fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
861 let mut bounds = Vec::new();
862
863 while self.can_begin_bound()
869 || (self.may_recover()
870 && (self.token.can_begin_type()
871 || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
872 {
873 if self.token.is_keyword(kw::Dyn) {
874 self.bump();
876 self.dcx().emit_err(InvalidDynKeyword {
877 span: self.prev_token.span,
878 suggestion: self.prev_token.span.until(self.token.span),
879 });
880 }
881 bounds.push(self.parse_generic_bound()?);
882 if allow_plus == AllowPlus::No || !self.eat_plus() {
883 break;
884 }
885 }
886
887 Ok(bounds)
888 }
889
890 fn can_begin_bound(&mut self) -> bool {
892 self.check_path()
893 || self.check_lifetime()
894 || self.check(exp!(Bang))
895 || self.check(exp!(Question))
896 || self.check(exp!(Tilde))
897 || self.check_keyword(exp!(For))
898 || self.check(exp!(OpenParen))
899 || self.check(exp!(OpenBracket))
900 || self.check_keyword(exp!(Const))
901 || self.check_keyword(exp!(Async))
902 || self.check_keyword(exp!(Use))
903 }
904
905 fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
910 let lo = self.token.span;
911 let leading_token = self.prev_token;
912 let parens = if self.eat(exp!(OpenParen)) { ast::Parens::Yes } else { ast::Parens::No };
913
914 let bound = if self.token.is_lifetime() {
915 self.parse_generic_lt_bound(lo, parens)?
916 } else if self.eat_keyword(exp!(Use)) {
917 let use_span = self.prev_token.span;
921 let (args, args_span) = self.parse_precise_capturing_args()?;
922 GenericBound::Use(args, use_span.to(args_span))
923 } else {
924 self.parse_generic_ty_bound(lo, parens, &leading_token)?
925 };
926
927 Ok(bound)
928 }
929
930 fn parse_generic_lt_bound(
935 &mut self,
936 lo: Span,
937 parens: ast::Parens,
938 ) -> PResult<'a, GenericBound> {
939 let lt = self.expect_lifetime();
940 let bound = GenericBound::Outlives(lt);
941 if let ast::Parens::Yes = parens {
942 self.recover_paren_lifetime(lo)?;
945 }
946 Ok(bound)
947 }
948
949 fn error_lt_bound_with_modifiers(
951 &self,
952 modifiers: TraitBoundModifiers,
953 binder_span: Option<Span>,
954 ) -> ErrorGuaranteed {
955 let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
956
957 match constness {
958 BoundConstness::Never => {}
959 BoundConstness::Always(span) | BoundConstness::Maybe(span) => {
960 return self
961 .dcx()
962 .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() });
963 }
964 }
965
966 match polarity {
967 BoundPolarity::Positive => {}
968 BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
969 return self
970 .dcx()
971 .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() });
972 }
973 }
974
975 match asyncness {
976 BoundAsyncness::Normal => {}
977 BoundAsyncness::Async(span) => {
978 return self
979 .dcx()
980 .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() });
981 }
982 }
983
984 if let Some(span) = binder_span {
985 return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" });
986 }
987
988 unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
989 }
990
991 fn recover_paren_lifetime(&mut self, lo: Span) -> PResult<'a, ()> {
993 self.expect(exp!(CloseParen))?;
994 let span = lo.to(self.prev_token.span);
995 let sugg = errors::RemoveParens { lo, hi: self.prev_token.span };
996
997 self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg });
998 Ok(())
999 }
1000
1001 fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
1013 let modifier_lo = self.token.span;
1014 let constness = self.parse_bound_constness()?;
1015
1016 let asyncness = if self.token_uninterpolated_span().at_least_rust_2018()
1017 && self.eat_keyword(exp!(Async))
1018 {
1019 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1020 BoundAsyncness::Async(self.prev_token.span)
1021 } else if self.may_recover()
1022 && self.token_uninterpolated_span().is_rust_2015()
1023 && self.is_kw_followed_by_ident(kw::Async)
1024 {
1025 self.bump(); self.dcx().emit_err(errors::AsyncBoundModifierIn2015 {
1027 span: self.prev_token.span,
1028 help: HelpUseLatestEdition::new(),
1029 });
1030 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1031 BoundAsyncness::Async(self.prev_token.span)
1032 } else {
1033 BoundAsyncness::Normal
1034 };
1035 let modifier_hi = self.prev_token.span;
1036
1037 let polarity = if self.eat(exp!(Question)) {
1038 BoundPolarity::Maybe(self.prev_token.span)
1039 } else if self.eat(exp!(Bang)) {
1040 self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
1041 BoundPolarity::Negative(self.prev_token.span)
1042 } else {
1043 BoundPolarity::Positive
1044 };
1045
1046 match polarity {
1048 BoundPolarity::Positive => {
1049 }
1051 BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1052 match (asyncness, constness) {
1053 (BoundAsyncness::Normal, BoundConstness::Never) => {
1054 }
1056 (_, _) => {
1057 let constness = constness.as_str();
1058 let asyncness = asyncness.as_str();
1059 let glue =
1060 if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
1061 let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
1062 self.dcx().emit_err(errors::PolarityAndModifiers {
1063 polarity_span,
1064 polarity: polarity.as_str(),
1065 modifiers_span: modifier_lo.to(modifier_hi),
1066 modifiers_concatenated,
1067 });
1068 }
1069 }
1070 }
1071 }
1072
1073 Ok(TraitBoundModifiers { constness, asyncness, polarity })
1074 }
1075
1076 pub fn parse_bound_constness(&mut self) -> PResult<'a, BoundConstness> {
1077 Ok(if self.eat(exp!(Tilde)) {
1080 let tilde = self.prev_token.span;
1081 self.expect_keyword(exp!(Const))?;
1082 let span = tilde.to(self.prev_token.span);
1083 self.psess.gated_spans.gate(sym::const_trait_impl, span);
1084 BoundConstness::Maybe(span)
1085 } else if self.check(exp!(OpenBracket))
1086 && self.look_ahead(1, |t| t.is_keyword(kw::Const))
1087 && self.look_ahead(2, |t| *t == token::CloseBracket)
1088 {
1089 let start = self.token.span;
1090 self.bump();
1091 self.expect_keyword(exp!(Const)).unwrap();
1092 self.bump();
1093 let span = start.to(self.prev_token.span);
1094 self.psess.gated_spans.gate(sym::const_trait_impl, span);
1095 BoundConstness::Maybe(span)
1096 } else if self.eat_keyword(exp!(Const)) {
1097 self.psess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span);
1098 BoundConstness::Always(self.prev_token.span)
1099 } else {
1100 BoundConstness::Never
1101 })
1102 }
1103
1104 fn parse_generic_ty_bound(
1112 &mut self,
1113 lo: Span,
1114 parens: ast::Parens,
1115 leading_token: &Token,
1116 ) -> PResult<'a, GenericBound> {
1117 let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
1118
1119 let modifiers_lo = self.token.span;
1120 let modifiers = self.parse_trait_bound_modifiers()?;
1121 let modifiers_span = modifiers_lo.to(self.prev_token.span);
1122
1123 if let Some(binder_span) = binder_span {
1124 match modifiers.polarity {
1125 BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1126 self.dcx().emit_err(errors::BinderAndPolarity {
1127 binder_span,
1128 polarity_span,
1129 polarity: modifiers.polarity.as_str(),
1130 });
1131 }
1132 BoundPolarity::Positive => {}
1133 }
1134 }
1135
1136 if self.token.is_lifetime() {
1139 let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
1140 return self.parse_generic_lt_bound(lo, parens);
1141 }
1142
1143 if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
1144 lifetime_defs.extend(more_lifetime_defs);
1145 self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
1146 }
1147
1148 let mut path = if self.token.is_keyword(kw::Fn)
1149 && self.look_ahead(1, |t| *t == TokenKind::OpenParen)
1150 && let Some(path) = self.recover_path_from_fn()
1151 {
1152 path
1153 } else if !self.token.is_path_start() && self.token.can_begin_type() {
1154 let ty = self.parse_ty_no_plus()?;
1155 let mut err = self.dcx().struct_span_err(ty.span, "expected a trait, found type");
1157
1158 let path = if self.may_recover() {
1163 let (span, message, sugg, path, applicability) = match &ty.kind {
1164 TyKind::Ptr(..) | TyKind::Ref(..)
1165 if let TyKind::Path(_, path) = &ty.peel_refs().kind =>
1166 {
1167 (
1168 ty.span.until(path.span),
1169 "consider removing the indirection",
1170 "",
1171 path,
1172 Applicability::MaybeIncorrect,
1173 )
1174 }
1175 TyKind::ImplTrait(_, bounds)
1176 if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
1177 {
1178 (
1179 ty.span.until(tr.span),
1180 "use the trait bounds directly",
1181 "",
1182 &tr.trait_ref.path,
1183 Applicability::MachineApplicable,
1184 )
1185 }
1186 _ => return Err(err),
1187 };
1188
1189 err.span_suggestion_verbose(span, message, sugg, applicability);
1190
1191 path.clone()
1192 } else {
1193 return Err(err);
1194 };
1195
1196 err.emit();
1197
1198 path
1199 } else {
1200 self.parse_path(PathStyle::Type)?
1201 };
1202
1203 if self.may_recover() && self.token == TokenKind::OpenParen {
1204 self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
1205 }
1206
1207 if let ast::Parens::Yes = parens {
1208 if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1211 let bounds = vec![];
1212 self.parse_remaining_bounds(bounds, true)?;
1213 self.expect(exp!(CloseParen))?;
1214 self.dcx().emit_err(errors::IncorrectParensTraitBounds {
1215 span: vec![lo, self.prev_token.span],
1216 sugg: errors::IncorrectParensTraitBoundsSugg {
1217 wrong_span: leading_token.span.shrink_to_hi().to(lo),
1218 new_span: leading_token.span.shrink_to_lo(),
1219 },
1220 });
1221 } else {
1222 self.expect(exp!(CloseParen))?;
1223 }
1224 }
1225
1226 let poly_trait =
1227 PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span), parens);
1228 Ok(GenericBound::Trait(poly_trait))
1229 }
1230
1231 fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1233 let fn_token_span = self.token.span;
1234 self.bump();
1235 let args_lo = self.token.span;
1236 let snapshot = self.create_snapshot_for_diagnostic();
1237 match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1238 Ok(decl) => {
1239 self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1240 Some(ast::Path {
1241 span: fn_token_span.to(self.prev_token.span),
1242 segments: thin_vec![ast::PathSegment {
1243 ident: Ident::new(sym::Fn, fn_token_span),
1244 id: DUMMY_NODE_ID,
1245 args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
1246 span: args_lo.to(self.prev_token.span),
1247 inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
1248 inputs_span: args_lo.until(decl.output.span()),
1249 output: decl.output.clone(),
1250 }))),
1251 }],
1252 tokens: None,
1253 })
1254 }
1255 Err(diag) => {
1256 diag.cancel();
1257 self.restore_snapshot(snapshot);
1258 None
1259 }
1260 }
1261 }
1262
1263 pub(super) fn parse_late_bound_lifetime_defs(
1265 &mut self,
1266 ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
1267 if self.eat_keyword(exp!(For)) {
1268 let lo = self.token.span;
1269 self.expect_lt()?;
1270 let params = self.parse_generic_params()?;
1271 self.expect_gt()?;
1272 Ok((params, Some(lo.to(self.prev_token.span))))
1275 } else {
1276 Ok((ThinVec::new(), None))
1277 }
1278 }
1279
1280 fn recover_fn_trait_with_lifetime_params(
1284 &mut self,
1285 fn_path: &mut ast::Path,
1286 lifetime_defs: &mut ThinVec<GenericParam>,
1287 ) -> PResult<'a, ()> {
1288 let fn_path_segment = fn_path.segments.last_mut().unwrap();
1289 let generic_args = if let Some(p_args) = &fn_path_segment.args {
1290 *p_args.clone()
1291 } else {
1292 return Ok(());
1295 };
1296 let lifetimes =
1297 if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1298 &generic_args
1299 {
1300 args.into_iter()
1301 .filter_map(|arg| {
1302 if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1303 && let ast::GenericArg::Lifetime(lifetime) = generic_arg
1304 {
1305 Some(lifetime)
1306 } else {
1307 None
1308 }
1309 })
1310 .collect()
1311 } else {
1312 Vec::new()
1313 };
1314 if lifetimes.is_empty() {
1316 return Ok(());
1317 }
1318
1319 let inputs_lo = self.token.span;
1321 let inputs: ThinVec<_> =
1322 self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
1323 let inputs_span = inputs_lo.to(self.prev_token.span);
1324 let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
1325 let args = ast::ParenthesizedArgs {
1326 span: fn_path_segment.span().to(self.prev_token.span),
1327 inputs,
1328 inputs_span,
1329 output,
1330 }
1331 .into();
1332 *fn_path_segment = ast::PathSegment {
1333 ident: fn_path_segment.ident,
1334 args: Some(args),
1335 id: ast::DUMMY_NODE_ID,
1336 };
1337
1338 let mut generic_params = lifetimes
1340 .iter()
1341 .map(|lt| GenericParam {
1342 id: lt.id,
1343 ident: lt.ident,
1344 attrs: ast::AttrVec::new(),
1345 bounds: Vec::new(),
1346 is_placeholder: false,
1347 kind: ast::GenericParamKind::Lifetime,
1348 colon_span: None,
1349 })
1350 .collect::<ThinVec<GenericParam>>();
1351 lifetime_defs.append(&mut generic_params);
1352
1353 let generic_args_span = generic_args.span();
1354 let snippet = format!(
1355 "for<{}> ",
1356 lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1357 );
1358 let before_fn_path = fn_path.span.shrink_to_lo();
1359 self.dcx()
1360 .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
1361 .with_multipart_suggestion(
1362 "consider using a higher-ranked trait bound instead",
1363 vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1364 Applicability::MaybeIncorrect,
1365 )
1366 .emit();
1367 Ok(())
1368 }
1369
1370 pub(super) fn check_lifetime(&mut self) -> bool {
1371 self.expected_token_types.insert(TokenType::Lifetime);
1372 self.token.is_lifetime()
1373 }
1374
1375 pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1377 if let Some((ident, is_raw)) = self.token.lifetime() {
1378 if matches!(is_raw, IdentIsRaw::No)
1379 && ident.without_first_quote().is_reserved()
1380 && ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
1381 {
1382 self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
1383 }
1384
1385 self.bump();
1386 Lifetime { ident, id: ast::DUMMY_NODE_ID }
1387 } else {
1388 self.dcx().span_bug(self.token.span, "not a lifetime")
1389 }
1390 }
1391
1392 pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
1393 P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1394 }
1395}