@@ -6,7 +6,7 @@ use rustc_errors::{
66 Applicability , Diag , ErrorGuaranteed , MultiSpan , listify, pluralize, struct_span_code_err,
77} ;
88use rustc_hir as hir;
9- use rustc_hir:: def:: { DefKind , Res } ;
9+ use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
1010use rustc_hir:: def_id:: DefId ;
1111use rustc_middle:: bug;
1212use rustc_middle:: ty:: fast_reject:: { TreatParams , simplify_type} ;
@@ -1027,7 +1027,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10271027 & self ,
10281028 segments : impl Iterator < Item = & ' a hir:: PathSegment < ' a > > + Clone ,
10291029 args_visitors : impl Iterator < Item = & ' a hir:: GenericArg < ' a > > + Clone ,
1030- err_extend : GenericsArgsErrExtend < ' _ > ,
1030+ err_extend : GenericsArgsErrExtend < ' a > ,
10311031 ) -> ErrorGuaranteed {
10321032 #[ derive( PartialEq , Eq , Hash ) ]
10331033 enum ProhibitGenericsArg {
@@ -1047,23 +1047,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10471047 } ;
10481048 } ) ;
10491049
1050+ let segments: Vec < _ > = segments. collect ( ) ;
10501051 let types_and_spans: Vec < _ > = segments
1051- . clone ( )
1052+ . iter ( )
10521053 . flat_map ( |segment| {
10531054 if segment. args ( ) . args . is_empty ( ) {
10541055 None
10551056 } else {
10561057 Some ( (
10571058 match segment. res {
1058- hir :: def :: Res :: PrimTy ( ty) => {
1059+ Res :: PrimTy ( ty) => {
10591060 format ! ( "{} `{}`" , segment. res. descr( ) , ty. name( ) )
10601061 }
1061- hir :: def :: Res :: Def ( _, def_id)
1062+ Res :: Def ( _, def_id)
10621063 if let Some ( name) = self . tcx ( ) . opt_item_name ( def_id) =>
10631064 {
10641065 format ! ( "{} `{name}`" , segment. res. descr( ) )
10651066 }
1066- hir :: def :: Res :: Err => "this type" . to_string ( ) ,
1067+ Res :: Err => "this type" . to_string ( ) ,
10671068 _ => segment. res . descr ( ) . to_string ( ) ,
10681069 } ,
10691070 segment. ident . span ,
@@ -1074,11 +1075,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10741075 let this_type = listify ( & types_and_spans, |( t, _) | t. to_string ( ) )
10751076 . expect ( "expected one segment to deny" ) ;
10761077
1077- let arg_spans: Vec < Span > = segments
1078- . clone ( )
1079- . flat_map ( |segment| segment. args ( ) . args )
1080- . map ( |arg| arg. span ( ) )
1081- . collect ( ) ;
1078+ let arg_spans: Vec < Span > =
1079+ segments. iter ( ) . flat_map ( |segment| segment. args ( ) . args ) . map ( |arg| arg. span ( ) ) . collect ( ) ;
10821080
10831081 let mut kinds = Vec :: with_capacity ( 4 ) ;
10841082 prohibit_args. iter ( ) . for_each ( |arg| match arg {
@@ -1103,7 +1101,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11031101 for ( what, span) in types_and_spans {
11041102 err. span_label ( span, format ! ( "not allowed on {what}" ) ) ;
11051103 }
1106- generics_args_err_extend ( self . tcx ( ) , segments, & mut err, err_extend) ;
1104+ generics_args_err_extend ( self . tcx ( ) , segments. into_iter ( ) , & mut err, err_extend) ;
11071105 err. emit ( )
11081106 }
11091107
@@ -1400,15 +1398,15 @@ pub enum GenericsArgsErrExtend<'tcx> {
14001398 } ,
14011399 SelfTyParam ( Span ) ,
14021400 Param ( DefId ) ,
1403- DefVariant ,
1401+ DefVariant ( & ' tcx [ hir :: PathSegment < ' tcx > ] ) ,
14041402 None ,
14051403}
14061404
14071405fn generics_args_err_extend < ' a > (
14081406 tcx : TyCtxt < ' _ > ,
14091407 segments : impl Iterator < Item = & ' a hir:: PathSegment < ' a > > + Clone ,
14101408 err : & mut Diag < ' _ > ,
1411- err_extend : GenericsArgsErrExtend < ' _ > ,
1409+ err_extend : GenericsArgsErrExtend < ' a > ,
14121410) {
14131411 match err_extend {
14141412 GenericsArgsErrExtend :: EnumVariant { qself, assoc_segment, adt_def } => {
@@ -1496,6 +1494,32 @@ fn generics_args_err_extend<'a>(
14961494 ] ;
14971495 err. multipart_suggestion_verbose ( msg, suggestion, Applicability :: MaybeIncorrect ) ;
14981496 }
1497+ GenericsArgsErrExtend :: DefVariant ( segments) => {
1498+ let args: Vec < Span > = segments
1499+ . iter ( )
1500+ . filter_map ( |segment| match segment. res {
1501+ Res :: Def (
1502+ DefKind :: Ctor ( CtorOf :: Variant , _) | DefKind :: Variant | DefKind :: Enum ,
1503+ _,
1504+ ) => segment. args ( ) . span_ext ( ) . map ( |s| s. with_lo ( segment. ident . span . hi ( ) ) ) ,
1505+ _ => None ,
1506+ } )
1507+ . collect ( ) ;
1508+ if args. len ( ) > 1
1509+ && let Some ( span) = args. into_iter ( ) . last ( )
1510+ {
1511+ err. note (
1512+ "generic arguments are not allowed on both an enum and its variant's path \
1513+ segments simultaneously; they are only valid in one place or the other",
1514+ ) ;
1515+ err. span_suggestion_verbose (
1516+ span,
1517+ "remove the generics arguments from one of the path segments" ,
1518+ String :: new ( ) ,
1519+ Applicability :: MaybeIncorrect ,
1520+ ) ;
1521+ }
1522+ }
14991523 GenericsArgsErrExtend :: PrimTy ( prim_ty) => {
15001524 let name = prim_ty. name_str ( ) ;
15011525 for segment in segments {
@@ -1512,9 +1536,6 @@ fn generics_args_err_extend<'a>(
15121536 GenericsArgsErrExtend :: OpaqueTy => {
15131537 err. note ( "`impl Trait` types can't have type parameters" ) ;
15141538 }
1515- GenericsArgsErrExtend :: DefVariant => {
1516- err. note ( "enum variants can't have type parameters" ) ;
1517- }
15181539 GenericsArgsErrExtend :: Param ( def_id) => {
15191540 let span = tcx. def_ident_span ( def_id) . unwrap ( ) ;
15201541 let kind = tcx. def_descr ( def_id) ;
0 commit comments