1use rustc_ast::ptr::P;
2use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind};
3use rustc_ast::util::case::Case;
4use rustc_ast::{
5 self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
6 GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
7 Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
8 TyKind, UnsafeBinderTy,
9};
10use rustc_data_structures::stack::ensure_sufficient_stack;
11use rustc_errors::{Applicability, Diag, PResult};
12use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
13use thin_vec::{ThinVec, thin_vec};
14
15use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
16use crate::errors::{
17 self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
18 FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword,
19 LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
20 ReturnTypesUseThinArrow,
21};
22use crate::parser::item::FrontMatterParsingMode;
23use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
24
25#[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_bare_fn(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_bare_fn(
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 =
309 self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?;
310 let err = self.dcx().create_err(errors::TransposeDynOrImpl {
311 span: kw.span,
312 kw: kw.name.as_str(),
313 sugg: errors::TransposeDynOrImplSugg {
314 removal_span,
315 insertion_span: lo.shrink_to_lo(),
316 kw: kw.name.as_str(),
317 },
318 });
319
320 let kind = match (kind, kw.name) {
323 (TyKind::TraitObject(bounds, _), kw::Dyn) => {
324 TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
325 }
326 (TyKind::TraitObject(bounds, _), kw::Impl) => {
327 TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
328 }
329 _ => return Err(err),
330 };
331 err.emit();
332 kind
333 } else {
334 let path = self.parse_path(PathStyle::Type)?;
335 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
336 self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
337 }
338 }
339 } else if self.eat_keyword(exp!(Impl)) {
340 self.parse_impl_ty(&mut impl_dyn_multi)?
341 } else if self.is_explicit_dyn_type() {
342 self.parse_dyn_ty(&mut impl_dyn_multi)?
343 } else if self.eat_lt() {
344 let (qself, path) = self.parse_qpath(PathStyle::Type)?;
346 TyKind::Path(Some(qself), path)
347 } else if self.check_path() {
348 self.parse_path_start_ty(lo, allow_plus, ty_generics)?
349 } else if self.can_begin_bound() {
350 self.parse_bare_trait_object(lo, allow_plus)?
351 } else if self.eat(exp!(DotDotDot)) {
352 match allow_c_variadic {
353 AllowCVariadic::Yes => TyKind::CVarArgs,
354 AllowCVariadic::No => {
355 let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
359 TyKind::Err(guar)
360 }
361 }
362 } else if self.check_keyword(exp!(Unsafe))
363 && self.look_ahead(1, |tok| tok.kind == token::Lt)
364 {
365 self.parse_unsafe_binder_ty()?
366 } else {
367 let msg = format!("expected type, found {}", super::token_descr(&self.token));
368 let mut err = self.dcx().struct_span_err(lo, msg);
369 err.span_label(lo, "expected type");
370 return Err(err);
371 };
372
373 let span = lo.to(self.prev_token.span);
374 let mut ty = self.mk_ty(span, kind);
375
376 match allow_plus {
378 AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
379 AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
380 }
381 if let RecoverQuestionMark::Yes = recover_question_mark {
382 ty = self.maybe_recover_from_question_mark(ty);
383 }
384 if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
385 }
386
387 fn parse_unsafe_binder_ty(&mut self) -> PResult<'a, TyKind> {
388 let lo = self.token.span;
389 assert!(self.eat_keyword(exp!(Unsafe)));
390 self.expect_lt()?;
391 let generic_params = self.parse_generic_params()?;
392 self.expect_gt()?;
393 let inner_ty = self.parse_ty()?;
394 let span = lo.to(self.prev_token.span);
395 self.psess.gated_spans.gate(sym::unsafe_binders, span);
396
397 Ok(TyKind::UnsafeBinder(P(UnsafeBinderTy { generic_params, inner_ty })))
398 }
399
400 fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
404 let mut trailing_plus = false;
405 let (ts, trailing) = self.parse_paren_comma_seq(|p| {
406 let ty = p.parse_ty()?;
407 trailing_plus = p.prev_token == TokenKind::Plus;
408 Ok(ty)
409 })?;
410
411 if ts.len() == 1 && matches!(trailing, Trailing::No) {
412 let ty = ts.into_iter().next().unwrap();
413 let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
414 match ty.kind {
415 TyKind::Path(None, path) if maybe_bounds => {
417 self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
418 }
419 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
423 if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
424 {
425 self.parse_remaining_bounds(bounds, true)
426 }
427 _ => Ok(TyKind::Paren(ty)),
429 }
430 } else {
431 Ok(TyKind::Tup(ts))
432 }
433 }
434
435 fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
436 if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) {
438 if self.psess.edition.at_least_rust_2021() {
442 let lt = self.expect_lifetime();
443 let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime");
444 err.span_label(lo, "expected type");
445 return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) {
446 Ok(ref_ty) => ref_ty,
447 Err(err) => TyKind::Err(err.emit()),
448 });
449 }
450
451 self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime {
452 span: lo,
453 suggestion: lo.shrink_to_hi(),
454 });
455 }
456 Ok(TyKind::TraitObject(
457 self.parse_generic_bounds_common(allow_plus)?,
458 TraitObjectSyntax::None,
459 ))
460 }
461
462 fn maybe_recover_ref_ty_no_leading_ampersand<'cx>(
463 &mut self,
464 lt: Lifetime,
465 lo: Span,
466 mut err: Diag<'cx>,
467 ) -> Result<TyKind, Diag<'cx>> {
468 if !self.may_recover() {
469 return Err(err);
470 }
471 let snapshot = self.create_snapshot_for_diagnostic();
472 let mutbl = self.parse_mutability();
473 match self.parse_ty_no_plus() {
474 Ok(ty) => {
475 err.span_suggestion_verbose(
476 lo.shrink_to_lo(),
477 "you might have meant to write a reference type here",
478 "&",
479 Applicability::MaybeIncorrect,
480 );
481 err.emit();
482 Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl }))
483 }
484 Err(diag) => {
485 diag.cancel();
486 self.restore_snapshot(snapshot);
487 Err(err)
488 }
489 }
490 }
491
492 fn parse_remaining_bounds_path(
493 &mut self,
494 generic_params: ThinVec<GenericParam>,
495 path: ast::Path,
496 lo: Span,
497 parse_plus: bool,
498 ) -> PResult<'a, TyKind> {
499 let poly_trait_ref = PolyTraitRef::new(
500 generic_params,
501 path,
502 TraitBoundModifiers::NONE,
503 lo.to(self.prev_token.span),
504 );
505 let bounds = vec![GenericBound::Trait(poly_trait_ref)];
506 self.parse_remaining_bounds(bounds, parse_plus)
507 }
508
509 fn parse_remaining_bounds(
511 &mut self,
512 mut bounds: GenericBounds,
513 plus: bool,
514 ) -> PResult<'a, TyKind> {
515 if plus {
516 self.eat_plus(); bounds.append(&mut self.parse_generic_bounds()?);
518 }
519 Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
520 }
521
522 fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
524 let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
525 let span = self.prev_token.span;
526 self.dcx().emit_err(ExpectedMutOrConstInRawPointerType {
527 span,
528 after_asterisk: span.shrink_to_hi(),
529 });
530 Mutability::Not
531 });
532 let ty = self.parse_ty_no_plus()?;
533 Ok(TyKind::Ptr(MutTy { ty, mutbl }))
534 }
535
536 fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
539 let elt_ty = match self.parse_ty() {
540 Ok(ty) => ty,
541 Err(err)
542 if self.look_ahead(1, |t| *t == token::CloseBracket)
543 | self.look_ahead(1, |t| *t == token::Semi) =>
544 {
545 self.bump();
547 let guar = err.emit();
548 self.mk_ty(self.prev_token.span, TyKind::Err(guar))
549 }
550 Err(err) => return Err(err),
551 };
552
553 let ty = if self.eat(exp!(Semi)) {
554 let mut length = self.parse_expr_anon_const()?;
555 if let Err(e) = self.expect(exp!(CloseBracket)) {
556 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
558 self.expect(exp!(CloseBracket))?;
559 }
560 TyKind::Array(elt_ty, length)
561 } else {
562 self.expect(exp!(CloseBracket))?;
563 TyKind::Slice(elt_ty)
564 };
565
566 Ok(ty)
567 }
568
569 fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
570 let and_span = self.prev_token.span;
571 let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
572 let (pinned, mut mutbl) = match self.parse_pin_and_mut() {
573 Some(pin_mut) => pin_mut,
574 None => (Pinnedness::Not, self.parse_mutability()),
575 };
576 if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
577 if !self.look_ahead(1, |t| t.is_like_plus()) {
583 let lifetime_span = self.token.span;
584 let span = and_span.to(lifetime_span);
585
586 let (suggest_lifetime, snippet) =
587 if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
588 (Some(span), lifetime_src)
589 } else {
590 (None, String::new())
591 };
592 self.dcx().emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });
593
594 opt_lifetime = Some(self.expect_lifetime());
595 }
596 } else if self.token.is_keyword(kw::Dyn)
597 && mutbl == Mutability::Not
598 && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
599 {
600 let span = and_span.to(self.look_ahead(1, |t| t.span));
602 self.dcx().emit_err(DynAfterMut { span });
603
604 mutbl = Mutability::Mut;
606 let (dyn_tok, dyn_tok_sp) = (self.token, self.token_spacing);
607 self.bump();
608 self.bump_with((dyn_tok, dyn_tok_sp));
609 }
610 let ty = self.parse_ty_no_plus()?;
611 Ok(match pinned {
612 Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
613 Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
614 })
615 }
616
617 pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> {
621 if self.token.is_ident_named(sym::pin) {
622 let result = self.look_ahead(1, |token| {
623 if token.is_keyword(kw::Const) {
624 Some((Pinnedness::Pinned, Mutability::Not))
625 } else if token.is_keyword(kw::Mut) {
626 Some((Pinnedness::Pinned, Mutability::Mut))
627 } else {
628 None
629 }
630 });
631 if result.is_some() {
632 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
633 self.bump();
634 self.bump();
635 }
636 result
637 } else {
638 None
639 }
640 }
641
642 fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
645 self.expect(exp!(OpenParen))?;
646 let expr = self.parse_expr_anon_const()?;
647 self.expect(exp!(CloseParen))?;
648 Ok(TyKind::Typeof(expr))
649 }
650
651 fn parse_ty_bare_fn(
661 &mut self,
662 lo: Span,
663 mut params: ThinVec<GenericParam>,
664 param_insertion_point: Option<Span>,
665 recover_return_sign: RecoverReturnSign,
666 ) -> PResult<'a, TyKind> {
667 let inherited_vis = rustc_ast::Visibility {
668 span: rustc_span::DUMMY_SP,
669 kind: rustc_ast::VisibilityKind::Inherited,
670 tokens: None,
671 };
672 let span_start = self.token.span;
673 let ast::FnHeader { ext, safety, .. } = self.parse_fn_front_matter(
674 &inherited_vis,
675 Case::Sensitive,
676 FrontMatterParsingMode::FunctionPtrType,
677 )?;
678 if self.may_recover() && self.token == TokenKind::Lt {
679 self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
680 }
681 let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
682
683 let decl_span = span_start.to(self.prev_token.span);
684 Ok(TyKind::BareFn(P(BareFnTy { ext, safety, generic_params: params, decl, decl_span })))
685 }
686
687 fn recover_fn_ptr_with_generics(
689 &mut self,
690 lo: Span,
691 params: &mut ThinVec<GenericParam>,
692 param_insertion_point: Option<Span>,
693 ) -> PResult<'a, ()> {
694 let generics = self.parse_generics()?;
695 let arity = generics.params.len();
696
697 let mut lifetimes: ThinVec<_> = generics
698 .params
699 .into_iter()
700 .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
701 .collect();
702
703 let sugg = if !lifetimes.is_empty() {
704 let snippet =
705 lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
706
707 let (left, snippet) = if let Some(span) = param_insertion_point {
708 (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
709 } else {
710 (lo.shrink_to_lo(), format!("for<{snippet}> "))
711 };
712
713 Some(FnPtrWithGenericsSugg {
714 left,
715 snippet,
716 right: generics.span,
717 arity,
718 for_param_list_exists: param_insertion_point.is_some(),
719 })
720 } else {
721 None
722 };
723
724 self.dcx().emit_err(FnPtrWithGenerics { span: generics.span, sugg });
725 params.append(&mut lifetimes);
726 Ok(())
727 }
728
729 fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
731 if self.token.is_lifetime() {
732 self.look_ahead(1, |t| {
733 if let token::Ident(sym, _) = t.kind {
734 self.dcx().emit_err(errors::MissingPlusBounds {
737 span: self.token.span,
738 hi: self.token.span.shrink_to_hi(),
739 sym,
740 });
741 }
742 })
743 }
744
745 let bounds = self.parse_generic_bounds()?;
747
748 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
749
750 Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
751 }
752
753 fn parse_precise_capturing_args(
754 &mut self,
755 ) -> PResult<'a, (ThinVec<PreciseCapturingArg>, Span)> {
756 let lo = self.token.span;
757 self.expect_lt()?;
758 let (args, _, _) = self.parse_seq_to_before_tokens(
759 &[exp!(Gt)],
760 &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr],
761 SeqSep::trailing_allowed(exp!(Comma)),
762 |self_| {
763 if self_.check_keyword(exp!(SelfUpper)) {
764 self_.bump();
765 Ok(PreciseCapturingArg::Arg(
766 ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
767 DUMMY_NODE_ID,
768 ))
769 } else if self_.check_ident() {
770 Ok(PreciseCapturingArg::Arg(
771 ast::Path::from_ident(self_.parse_ident()?),
772 DUMMY_NODE_ID,
773 ))
774 } else if self_.check_lifetime() {
775 Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
776 } else {
777 self_.unexpected_any()
778 }
779 },
780 )?;
781 self.expect_gt()?;
782 Ok((args, lo.to(self.prev_token.span)))
783 }
784
785 fn is_explicit_dyn_type(&mut self) -> bool {
787 self.check_keyword(exp!(Dyn))
788 && (self.token_uninterpolated_span().at_least_rust_2018()
789 || self.look_ahead(1, |t| {
790 (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star)
791 && !can_continue_type_after_non_fn_ident(t)
792 }))
793 }
794
795 fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
799 let lo = self.token.span;
800 self.bump(); let syntax = if self.eat(exp!(Star)) {
804 self.psess.gated_spans.gate(sym::dyn_star, lo.to(self.prev_token.span));
805 TraitObjectSyntax::DynStar
806 } else {
807 TraitObjectSyntax::Dyn
808 };
809
810 let bounds = self.parse_generic_bounds()?;
812 *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
813 Ok(TyKind::TraitObject(bounds, syntax))
814 }
815
816 fn parse_path_start_ty(
823 &mut self,
824 lo: Span,
825 allow_plus: AllowPlus,
826 ty_generics: Option<&Generics>,
827 ) -> PResult<'a, TyKind> {
828 let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
830 if self.eat(exp!(Bang)) {
831 Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
833 } else if allow_plus == AllowPlus::Yes && self.check_plus() {
834 self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
836 } else {
837 Ok(TyKind::Path(None, path))
839 }
840 }
841
842 pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
843 self.parse_generic_bounds_common(AllowPlus::Yes)
844 }
845
846 fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
850 let mut bounds = Vec::new();
851
852 while self.can_begin_bound()
858 || (self.may_recover()
859 && (self.token.can_begin_type()
860 || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
861 {
862 if self.token.is_keyword(kw::Dyn) {
863 self.bump();
865 self.dcx().emit_err(InvalidDynKeyword {
866 span: self.prev_token.span,
867 suggestion: self.prev_token.span.until(self.token.span),
868 });
869 }
870 bounds.push(self.parse_generic_bound()?);
871 if allow_plus == AllowPlus::No || !self.eat_plus() {
872 break;
873 }
874 }
875
876 Ok(bounds)
877 }
878
879 fn can_begin_bound(&mut self) -> bool {
881 self.check_path()
882 || self.check_lifetime()
883 || self.check(exp!(Bang))
884 || self.check(exp!(Question))
885 || self.check(exp!(Tilde))
886 || self.check_keyword(exp!(For))
887 || self.check(exp!(OpenParen))
888 || self.check_keyword(exp!(Const))
889 || self.check_keyword(exp!(Async))
890 || self.check_keyword(exp!(Use))
891 }
892
893 fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
898 let lo = self.token.span;
899 let leading_token = self.prev_token;
900 let has_parens = self.eat(exp!(OpenParen));
901
902 let bound = if self.token.is_lifetime() {
903 self.parse_generic_lt_bound(lo, has_parens)?
904 } else if self.eat_keyword(exp!(Use)) {
905 let use_span = self.prev_token.span;
909 let (args, args_span) = self.parse_precise_capturing_args()?;
910 GenericBound::Use(args, use_span.to(args_span))
911 } else {
912 self.parse_generic_ty_bound(lo, has_parens, &leading_token)?
913 };
914
915 Ok(bound)
916 }
917
918 fn parse_generic_lt_bound(&mut self, lo: Span, has_parens: bool) -> PResult<'a, GenericBound> {
923 let lt = self.expect_lifetime();
924 let bound = GenericBound::Outlives(lt);
925 if has_parens {
926 self.recover_paren_lifetime(lo)?;
929 }
930 Ok(bound)
931 }
932
933 fn error_lt_bound_with_modifiers(
935 &self,
936 modifiers: TraitBoundModifiers,
937 binder_span: Option<Span>,
938 ) -> ErrorGuaranteed {
939 let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
940
941 match constness {
942 BoundConstness::Never => {}
943 BoundConstness::Always(span) | BoundConstness::Maybe(span) => {
944 return self
945 .dcx()
946 .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() });
947 }
948 }
949
950 match polarity {
951 BoundPolarity::Positive => {}
952 BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
953 return self
954 .dcx()
955 .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() });
956 }
957 }
958
959 match asyncness {
960 BoundAsyncness::Normal => {}
961 BoundAsyncness::Async(span) => {
962 return self
963 .dcx()
964 .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() });
965 }
966 }
967
968 if let Some(span) = binder_span {
969 return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" });
970 }
971
972 unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?")
973 }
974
975 fn recover_paren_lifetime(&mut self, lo: Span) -> PResult<'a, ()> {
977 self.expect(exp!(CloseParen))?;
978 let span = lo.to(self.prev_token.span);
979 let sugg = errors::RemoveParens { lo, hi: self.prev_token.span };
980
981 self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg });
982 Ok(())
983 }
984
985 fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
997 let modifier_lo = self.token.span;
998 let constness = if self.eat(exp!(Tilde)) {
999 let tilde = self.prev_token.span;
1000 self.expect_keyword(exp!(Const))?;
1001 let span = tilde.to(self.prev_token.span);
1002 self.psess.gated_spans.gate(sym::const_trait_impl, span);
1003 BoundConstness::Maybe(span)
1004 } else if self.eat_keyword(exp!(Const)) {
1005 self.psess.gated_spans.gate(sym::const_trait_impl, self.prev_token.span);
1006 BoundConstness::Always(self.prev_token.span)
1007 } else {
1008 BoundConstness::Never
1009 };
1010
1011 let asyncness = if self.token_uninterpolated_span().at_least_rust_2018()
1012 && self.eat_keyword(exp!(Async))
1013 {
1014 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1015 BoundAsyncness::Async(self.prev_token.span)
1016 } else if self.may_recover()
1017 && self.token_uninterpolated_span().is_rust_2015()
1018 && self.is_kw_followed_by_ident(kw::Async)
1019 {
1020 self.bump(); self.dcx().emit_err(errors::AsyncBoundModifierIn2015 {
1022 span: self.prev_token.span,
1023 help: HelpUseLatestEdition::new(),
1024 });
1025 self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
1026 BoundAsyncness::Async(self.prev_token.span)
1027 } else {
1028 BoundAsyncness::Normal
1029 };
1030 let modifier_hi = self.prev_token.span;
1031
1032 let polarity = if self.eat(exp!(Question)) {
1033 BoundPolarity::Maybe(self.prev_token.span)
1034 } else if self.eat(exp!(Bang)) {
1035 self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
1036 BoundPolarity::Negative(self.prev_token.span)
1037 } else {
1038 BoundPolarity::Positive
1039 };
1040
1041 match polarity {
1043 BoundPolarity::Positive => {
1044 }
1046 BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1047 match (asyncness, constness) {
1048 (BoundAsyncness::Normal, BoundConstness::Never) => {
1049 }
1051 (_, _) => {
1052 let constness = constness.as_str();
1053 let asyncness = asyncness.as_str();
1054 let glue =
1055 if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
1056 let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
1057 self.dcx().emit_err(errors::PolarityAndModifiers {
1058 polarity_span,
1059 polarity: polarity.as_str(),
1060 modifiers_span: modifier_lo.to(modifier_hi),
1061 modifiers_concatenated,
1062 });
1063 }
1064 }
1065 }
1066 }
1067
1068 Ok(TraitBoundModifiers { constness, asyncness, polarity })
1069 }
1070
1071 fn parse_generic_ty_bound(
1079 &mut self,
1080 lo: Span,
1081 has_parens: bool,
1082 leading_token: &Token,
1083 ) -> PResult<'a, GenericBound> {
1084 let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
1085
1086 let modifiers_lo = self.token.span;
1087 let modifiers = self.parse_trait_bound_modifiers()?;
1088 let modifiers_span = modifiers_lo.to(self.prev_token.span);
1089
1090 if let Some(binder_span) = binder_span {
1091 match modifiers.polarity {
1092 BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1093 self.dcx().emit_err(errors::BinderAndPolarity {
1094 binder_span,
1095 polarity_span,
1096 polarity: modifiers.polarity.as_str(),
1097 });
1098 }
1099 BoundPolarity::Positive => {}
1100 }
1101 }
1102
1103 if self.token.is_lifetime() {
1106 let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
1107 return self.parse_generic_lt_bound(lo, has_parens);
1108 }
1109
1110 if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
1111 lifetime_defs.extend(more_lifetime_defs);
1112 self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
1113 }
1114
1115 let mut path = if self.token.is_keyword(kw::Fn)
1116 && self.look_ahead(1, |t| *t == TokenKind::OpenParen)
1117 && let Some(path) = self.recover_path_from_fn()
1118 {
1119 path
1120 } else if !self.token.is_path_start() && self.token.can_begin_type() {
1121 let ty = self.parse_ty_no_plus()?;
1122 let mut err = self.dcx().struct_span_err(ty.span, "expected a trait, found type");
1124
1125 let path = if self.may_recover() {
1130 let (span, message, sugg, path, applicability) = match &ty.kind {
1131 TyKind::Ptr(..) | TyKind::Ref(..)
1132 if let TyKind::Path(_, path) = &ty.peel_refs().kind =>
1133 {
1134 (
1135 ty.span.until(path.span),
1136 "consider removing the indirection",
1137 "",
1138 path,
1139 Applicability::MaybeIncorrect,
1140 )
1141 }
1142 TyKind::ImplTrait(_, bounds)
1143 if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
1144 {
1145 (
1146 ty.span.until(tr.span),
1147 "use the trait bounds directly",
1148 "",
1149 &tr.trait_ref.path,
1150 Applicability::MachineApplicable,
1151 )
1152 }
1153 _ => return Err(err),
1154 };
1155
1156 err.span_suggestion_verbose(span, message, sugg, applicability);
1157
1158 path.clone()
1159 } else {
1160 return Err(err);
1161 };
1162
1163 err.emit();
1164
1165 path
1166 } else {
1167 self.parse_path(PathStyle::Type)?
1168 };
1169
1170 if self.may_recover() && self.token == TokenKind::OpenParen {
1171 self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
1172 }
1173
1174 if has_parens {
1175 if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1178 let bounds = vec![];
1179 self.parse_remaining_bounds(bounds, true)?;
1180 self.expect(exp!(CloseParen))?;
1181 self.dcx().emit_err(errors::IncorrectParensTraitBounds {
1182 span: vec![lo, self.prev_token.span],
1183 sugg: errors::IncorrectParensTraitBoundsSugg {
1184 wrong_span: leading_token.span.shrink_to_hi().to(lo),
1185 new_span: leading_token.span.shrink_to_lo(),
1186 },
1187 });
1188 } else {
1189 self.expect(exp!(CloseParen))?;
1190 }
1191 }
1192
1193 let poly_trait =
1194 PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
1195 Ok(GenericBound::Trait(poly_trait))
1196 }
1197
1198 fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
1200 let fn_token_span = self.token.span;
1201 self.bump();
1202 let args_lo = self.token.span;
1203 let snapshot = self.create_snapshot_for_diagnostic();
1204 match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
1205 Ok(decl) => {
1206 self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
1207 Some(ast::Path {
1208 span: fn_token_span.to(self.prev_token.span),
1209 segments: thin_vec![ast::PathSegment {
1210 ident: Ident::new(sym::Fn, fn_token_span),
1211 id: DUMMY_NODE_ID,
1212 args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
1213 span: args_lo.to(self.prev_token.span),
1214 inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
1215 inputs_span: args_lo.until(decl.output.span()),
1216 output: decl.output.clone(),
1217 }))),
1218 }],
1219 tokens: None,
1220 })
1221 }
1222 Err(diag) => {
1223 diag.cancel();
1224 self.restore_snapshot(snapshot);
1225 None
1226 }
1227 }
1228 }
1229
1230 pub(super) fn parse_late_bound_lifetime_defs(
1232 &mut self,
1233 ) -> PResult<'a, (ThinVec<GenericParam>, Option<Span>)> {
1234 if self.eat_keyword(exp!(For)) {
1235 let lo = self.token.span;
1236 self.expect_lt()?;
1237 let params = self.parse_generic_params()?;
1238 self.expect_gt()?;
1239 Ok((params, Some(lo.to(self.prev_token.span))))
1242 } else {
1243 Ok((ThinVec::new(), None))
1244 }
1245 }
1246
1247 fn recover_fn_trait_with_lifetime_params(
1251 &mut self,
1252 fn_path: &mut ast::Path,
1253 lifetime_defs: &mut ThinVec<GenericParam>,
1254 ) -> PResult<'a, ()> {
1255 let fn_path_segment = fn_path.segments.last_mut().unwrap();
1256 let generic_args = if let Some(p_args) = &fn_path_segment.args {
1257 *p_args.clone()
1258 } else {
1259 return Ok(());
1262 };
1263 let lifetimes =
1264 if let ast::GenericArgs::AngleBracketed(ast::AngleBracketedArgs { span: _, args }) =
1265 &generic_args
1266 {
1267 args.into_iter()
1268 .filter_map(|arg| {
1269 if let ast::AngleBracketedArg::Arg(generic_arg) = arg
1270 && let ast::GenericArg::Lifetime(lifetime) = generic_arg
1271 {
1272 Some(lifetime)
1273 } else {
1274 None
1275 }
1276 })
1277 .collect()
1278 } else {
1279 Vec::new()
1280 };
1281 if lifetimes.is_empty() {
1283 return Ok(());
1284 }
1285
1286 let inputs_lo = self.token.span;
1288 let inputs: ThinVec<_> =
1289 self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
1290 let inputs_span = inputs_lo.to(self.prev_token.span);
1291 let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
1292 let args = ast::ParenthesizedArgs {
1293 span: fn_path_segment.span().to(self.prev_token.span),
1294 inputs,
1295 inputs_span,
1296 output,
1297 }
1298 .into();
1299 *fn_path_segment = ast::PathSegment {
1300 ident: fn_path_segment.ident,
1301 args: Some(args),
1302 id: ast::DUMMY_NODE_ID,
1303 };
1304
1305 let mut generic_params = lifetimes
1307 .iter()
1308 .map(|lt| GenericParam {
1309 id: lt.id,
1310 ident: lt.ident,
1311 attrs: ast::AttrVec::new(),
1312 bounds: Vec::new(),
1313 is_placeholder: false,
1314 kind: ast::GenericParamKind::Lifetime,
1315 colon_span: None,
1316 })
1317 .collect::<ThinVec<GenericParam>>();
1318 lifetime_defs.append(&mut generic_params);
1319
1320 let generic_args_span = generic_args.span();
1321 let snippet = format!(
1322 "for<{}> ",
1323 lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
1324 );
1325 let before_fn_path = fn_path.span.shrink_to_lo();
1326 self.dcx()
1327 .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
1328 .with_multipart_suggestion(
1329 "consider using a higher-ranked trait bound instead",
1330 vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
1331 Applicability::MaybeIncorrect,
1332 )
1333 .emit();
1334 Ok(())
1335 }
1336
1337 pub(super) fn check_lifetime(&mut self) -> bool {
1338 self.expected_token_types.insert(TokenType::Lifetime);
1339 self.token.is_lifetime()
1340 }
1341
1342 pub(super) fn expect_lifetime(&mut self) -> Lifetime {
1344 if let Some((ident, is_raw)) = self.token.lifetime() {
1345 if matches!(is_raw, IdentIsRaw::No)
1346 && ident.without_first_quote().is_reserved()
1347 && ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
1348 {
1349 self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
1350 }
1351
1352 self.bump();
1353 Lifetime { ident, id: ast::DUMMY_NODE_ID }
1354 } else {
1355 self.dcx().span_bug(self.token.span, "not a lifetime")
1356 }
1357 }
1358
1359 pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
1360 P(Ty { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
1361 }
1362}