From 94a0819fe3a0d679c3042a77bfe6a2afc505daea Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:28 +0200 Subject: Adding upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_parse/src/parser/generics.rs | 45 ++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_parse/src/parser/generics.rs') diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 1acfd93d8..fa75670b2 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -2,7 +2,7 @@ use super::{ForceCollect, Parser, TrailingToken}; use rustc_ast::token; use rustc_ast::{ - self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause, + self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::kw; @@ -26,24 +26,54 @@ impl<'a> Parser<'a> { } /// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`. - fn parse_ty_param(&mut self, preceding_attrs: Vec) -> PResult<'a, GenericParam> { + fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> { let ident = self.parse_ident()?; // Parse optional colon and param bounds. let mut colon_span = None; let bounds = if self.eat(&token::Colon) { colon_span = Some(self.prev_token.span); + // recover from `impl Trait` in type param bound + if self.token.is_keyword(kw::Impl) { + let impl_span = self.token.span; + let snapshot = self.create_snapshot_for_diagnostic(); + match self.parse_ty() { + Ok(p) => { + if let TyKind::ImplTrait(_, bounds) = &(*p).kind { + let span = impl_span.to(self.token.span.shrink_to_lo()); + let mut err = self.struct_span_err( + span, + "expected trait bound, found `impl Trait` type", + ); + err.span_label(span, "not a trait"); + if let [bound, ..] = &bounds[..] { + err.span_suggestion_verbose( + impl_span.until(bound.span()), + "use the trait bounds directly", + String::new(), + Applicability::MachineApplicable, + ); + } + err.emit(); + return Err(err); + } + } + Err(err) => { + err.cancel(); + } + } + self.restore_snapshot(snapshot); + } self.parse_generic_bounds(colon_span)? } else { Vec::new() }; let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None }; - Ok(GenericParam { ident, id: ast::DUMMY_NODE_ID, - attrs: preceding_attrs.into(), + attrs: preceding_attrs, bounds, kind: GenericParamKind::Type { default }, is_placeholder: false, @@ -53,7 +83,7 @@ impl<'a> Parser<'a> { pub(crate) fn parse_const_param( &mut self, - preceding_attrs: Vec, + preceding_attrs: AttrVec, ) -> PResult<'a, GenericParam> { let const_span = self.token.span; @@ -68,7 +98,7 @@ impl<'a> Parser<'a> { Ok(GenericParam { ident, id: ast::DUMMY_NODE_ID, - attrs: preceding_attrs.into(), + attrs: preceding_attrs, bounds: Vec::new(), kind: GenericParamKind::Const { ty, kw_span: const_span, default }, is_placeholder: false, @@ -109,7 +139,7 @@ impl<'a> Parser<'a> { Some(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, - attrs: attrs.into(), + attrs, bounds, kind: ast::GenericParamKind::Lifetime, is_placeholder: false, @@ -314,7 +344,6 @@ impl<'a> Parser<'a> { span: lo.to(self.prev_token.span), lhs_ty: ty, rhs_ty, - id: ast::DUMMY_NODE_ID, })) } else { self.maybe_recover_bounds_doubled_colon(&ty)?; -- cgit v1.2.3