@@ -7,10 +7,10 @@ use rustc_hir::intravisit;
77use rustc_hir:: { GenericParamKind , ImplItemKind , TraitItemKind } ;
88use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
99use rustc_infer:: traits:: util;
10- use rustc_middle:: ty;
1110use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
1211use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
1312use rustc_middle:: ty:: util:: ExplicitSelf ;
13+ use rustc_middle:: ty:: { self , DefIdTree } ;
1414use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
1515use rustc_span:: Span ;
1616use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
@@ -48,7 +48,7 @@ crate fn compare_impl_method<'tcx>(
4848 return ;
4949 }
5050
51- if let Err ( _) = compare_generic_param_kinds ( tcx, impl_m, trait_m, trait_item_span ) {
51+ if let Err ( _) = compare_generic_param_kinds ( tcx, impl_m, trait_m) {
5252 return ;
5353 }
5454
@@ -973,7 +973,6 @@ fn compare_generic_param_kinds<'tcx>(
973973 tcx : TyCtxt < ' tcx > ,
974974 impl_item : & ty:: AssocItem ,
975975 trait_item : & ty:: AssocItem ,
976- trait_item_span : Option < Span > ,
977976) -> Result < ( ) , ErrorGuaranteed > {
978977 assert_eq ! ( impl_item. kind, trait_item. kind) ;
979978
@@ -986,123 +985,54 @@ fn compare_generic_param_kinds<'tcx>(
986985 } )
987986 } ;
988987
989- let get_param_span = |param : & ty:: GenericParamDef | match tcx. hir ( ) . get_if_local ( param. def_id ) {
990- Some ( hir:: Node :: GenericParam ( hir:: GenericParam { span, .. } ) ) => Some ( span) ,
991- _ => None ,
992- } ;
988+ for ( param_impl, param_trait) in
989+ iter:: zip ( ty_const_params_of ( impl_item. def_id ) , ty_const_params_of ( trait_item. def_id ) )
990+ {
991+ use GenericParamDefKind :: * ;
992+ if match ( & param_impl. kind , & param_trait. kind ) {
993+ ( Const { .. } , Const { .. } )
994+ if tcx. type_of ( param_impl. def_id ) != tcx. type_of ( param_trait. def_id ) =>
995+ {
996+ true
997+ }
998+ ( Const { .. } , Type { .. } ) | ( Type { .. } , Const { .. } ) => true ,
999+ // this is exhaustive so that anyone adding new generic param kinds knows
1000+ // to make sure this error is reported for them.
1001+ ( Const { .. } , Const { .. } ) | ( Type { .. } , Type { .. } ) => false ,
1002+ ( Lifetime { .. } , _) | ( _, Lifetime { .. } ) => unreachable ! ( ) ,
1003+ } {
1004+ let make_param_message = |prefix : & str , param : & ty:: GenericParamDef | match param. kind {
1005+ Const { .. } => {
1006+ format ! ( "{} const parameter with type `{}`" , prefix, tcx. type_of( param. def_id) )
1007+ }
1008+ Type { .. } => format ! ( "{} type parameter" , prefix) ,
1009+ Lifetime { .. } => unreachable ! ( ) ,
1010+ } ;
9931011
994- let get_param_ident = |param : & ty:: GenericParamDef | match tcx. hir ( ) . get_if_local ( param. def_id ) {
995- Some ( hir:: Node :: GenericParam ( hir:: GenericParam { name, .. } ) ) => match name {
996- hir:: ParamName :: Plain ( ident) => Some ( ident) ,
997- _ => None ,
998- } ,
999- other => bug ! (
1000- "expected GenericParam, found {:?}" ,
1001- other. map_or_else( || "nothing" . to_string( ) , |n| format!( "{:?}" , n) )
1002- ) ,
1003- } ;
1012+ let param_impl_span = tcx. def_span ( param_impl. def_id ) ;
1013+ let param_trait_span = tcx. def_span ( param_trait. def_id ) ;
10041014
1005- let ty_const_params_impl = ty_const_params_of ( impl_item. def_id ) ;
1006- let ty_const_params_trait = ty_const_params_of ( trait_item. def_id ) ;
1007- let assoc_item_str = assoc_item_kind_str ( & impl_item) ;
1015+ let mut err = struct_span_err ! (
1016+ tcx. sess,
1017+ param_impl_span,
1018+ E0053 ,
1019+ "{} `{}` has an incompatible generic parameter for trait: `{}`" ,
1020+ assoc_item_kind_str( & impl_item) ,
1021+ trait_item. name,
1022+ & tcx. def_path_str( tcx. parent( trait_item. def_id) )
1023+ ) ;
10081024
1009- for ( param_impl, param_trait) in iter:: zip ( ty_const_params_impl, ty_const_params_trait) {
1010- use GenericParamDefKind :: * ;
1011- match ( & param_impl. kind , & param_trait. kind ) {
1012- ( Const { .. } , Const { .. } ) => {
1013- let impl_ty = tcx. type_of ( param_impl. def_id ) ;
1014- let trait_ty = tcx. type_of ( param_trait. def_id ) ;
1015- if impl_ty != trait_ty {
1016- let param_impl_span = get_param_span ( param_impl) . unwrap ( ) ;
1017- let param_impl_ident = get_param_ident ( param_impl) ;
1018- let param_trait_span = get_param_span ( param_trait) ;
1019-
1020- let mut err = struct_span_err ! (
1021- tcx. sess,
1022- * param_impl_span,
1023- E0053 ,
1024- "{} `{}` has an incompatible const parameter type for trait" ,
1025- assoc_item_str,
1026- trait_item. name,
1027- ) ;
1028- err. span_note (
1029- param_trait_span. map_or_else (
1030- || trait_item_span. unwrap_or ( * param_impl_span) ,
1031- |span| * span,
1032- ) ,
1033- & format ! (
1034- "the const parameter{} has type `{}`, but the declaration \
1035- in trait `{}` has type `{}`",
1036- & param_impl_ident
1037- . map_or_else( || "" . to_string( ) , |ident| format!( " `{ident}`" ) ) ,
1038- impl_ty,
1039- tcx. def_path_str( trait_item. def_id) ,
1040- trait_ty
1041- ) ,
1042- ) ;
1043- let reported = err. emit ( ) ;
1044- return Err ( reported) ;
1045- }
1046- }
1047- ( Const { .. } , Type { .. } ) => {
1048- let impl_ty = tcx. type_of ( param_impl. def_id ) ;
1049- let param_impl_span = get_param_span ( param_impl) . unwrap ( ) ;
1050- let param_impl_ident = get_param_ident ( param_impl) ;
1051- let param_trait_span = get_param_span ( param_trait) ;
1052-
1053- let mut err = struct_span_err ! (
1054- tcx. sess,
1055- * param_impl_span,
1056- E0053 ,
1057- "{} `{}` has an incompatible generic parameter for trait" ,
1058- assoc_item_str,
1059- trait_item. name,
1060- ) ;
1061- err. span_note (
1062- param_trait_span
1063- . map_or_else ( || trait_item_span. unwrap_or ( * param_impl_span) , |span| * span) ,
1064- & format ! (
1065- "the trait impl specifies{} a const parameter of type `{}`, but the declaration \
1066- in trait `{}` requires it is a type parameter",
1067- & param_impl_ident
1068- . map_or_else( || "" . to_string( ) , |ident| format!( " `{ident}` is" ) ) ,
1069- impl_ty,
1070- tcx. def_path_str( trait_item. def_id) ,
1071- ) ,
1072- ) ;
1073- let reported = err. emit ( ) ;
1074- return Err ( reported) ;
1075- }
1076- ( Type { .. } , Const { .. } ) => {
1077- let trait_ty = tcx. type_of ( param_trait. def_id ) ;
1078- let param_impl_span = get_param_span ( param_impl) . unwrap ( ) ;
1079- let param_impl_ident = get_param_ident ( param_impl) ;
1080- let param_trait_span = get_param_span ( param_trait) ;
1081-
1082- let mut err = struct_span_err ! (
1083- tcx. sess,
1084- * param_impl_span,
1085- E0053 ,
1086- "{} `{}` has an incompatible generic parameter for trait" ,
1087- assoc_item_str,
1088- trait_item. name,
1089- ) ;
1090- err. span_note (
1091- param_trait_span
1092- . map_or_else ( || trait_item_span. unwrap_or ( * param_impl_span) , |span| * span) ,
1093- & format ! (
1094- "the trait impl specifies{} a type parameter, but the declaration \
1095- in trait `{}` requires it is a const parameter of type `{}`",
1096- & param_impl_ident
1097- . map_or_else( || "" . to_string( ) , |ident| format!( " `{ident}` is" ) ) ,
1098- tcx. def_path_str( trait_item. def_id) ,
1099- trait_ty,
1100- ) ,
1101- ) ;
1102- let reported = err. emit ( ) ;
1103- return Err ( reported) ;
1104- }
1105- _ => ( ) ,
1025+ let trait_header_span = tcx. def_ident_span ( tcx. parent ( trait_item. def_id ) ) . unwrap ( ) ;
1026+ err. span_label ( trait_header_span, "" ) ;
1027+ err. span_label ( param_trait_span, make_param_message ( "expected" , param_trait) ) ;
1028+
1029+ let impl_header_span =
1030+ tcx. sess . source_map ( ) . guess_head_span ( tcx. def_span ( tcx. parent ( impl_item. def_id ) ) ) ;
1031+ err. span_label ( impl_header_span, "" ) ;
1032+ err. span_label ( param_impl_span, make_param_message ( "found" , param_impl) ) ;
1033+
1034+ let reported = err. emit ( ) ;
1035+ return Err ( reported) ;
11061036 }
11071037 }
11081038
@@ -1228,7 +1158,7 @@ crate fn compare_ty_impl<'tcx>(
12281158 let _: Result < ( ) , ErrorGuaranteed > = ( || {
12291159 compare_number_of_generics ( tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span) ?;
12301160
1231- compare_generic_param_kinds ( tcx, impl_ty, trait_ty, trait_item_span ) ?;
1161+ compare_generic_param_kinds ( tcx, impl_ty, trait_ty) ?;
12321162
12331163 let sp = tcx. def_span ( impl_ty. def_id ) ;
12341164 compare_type_predicate_entailment ( tcx, impl_ty, sp, trait_ty, impl_trait_ref) ?;
0 commit comments