@@ -7,10 +7,10 @@ use rustc_hir::intravisit;
7
7
use rustc_hir:: { GenericParamKind , ImplItemKind , TraitItemKind } ;
8
8
use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
9
9
use rustc_infer:: traits:: util;
10
- use rustc_middle:: ty;
11
10
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
12
11
use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
13
12
use rustc_middle:: ty:: util:: ExplicitSelf ;
13
+ use rustc_middle:: ty:: { self , DefIdTree } ;
14
14
use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
15
15
use rustc_span:: Span ;
16
16
use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
@@ -48,7 +48,7 @@ crate fn compare_impl_method<'tcx>(
48
48
return ;
49
49
}
50
50
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) {
52
52
return ;
53
53
}
54
54
@@ -973,7 +973,6 @@ fn compare_generic_param_kinds<'tcx>(
973
973
tcx : TyCtxt < ' tcx > ,
974
974
impl_item : & ty:: AssocItem ,
975
975
trait_item : & ty:: AssocItem ,
976
- trait_item_span : Option < Span > ,
977
976
) -> Result < ( ) , ErrorGuaranteed > {
978
977
assert_eq ! ( impl_item. kind, trait_item. kind) ;
979
978
@@ -986,123 +985,54 @@ fn compare_generic_param_kinds<'tcx>(
986
985
} )
987
986
} ;
988
987
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
+ } ;
993
1011
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 ) ;
1004
1014
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
+ ) ;
1008
1024
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) ;
1106
1036
}
1107
1037
}
1108
1038
@@ -1228,7 +1158,7 @@ crate fn compare_ty_impl<'tcx>(
1228
1158
let _: Result < ( ) , ErrorGuaranteed > = ( || {
1229
1159
compare_number_of_generics ( tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span) ?;
1230
1160
1231
- compare_generic_param_kinds ( tcx, impl_ty, trait_ty, trait_item_span ) ?;
1161
+ compare_generic_param_kinds ( tcx, impl_ty, trait_ty) ?;
1232
1162
1233
1163
let sp = tcx. def_span ( impl_ty. def_id ) ;
1234
1164
compare_type_predicate_entailment ( tcx, impl_ty, sp, trait_ty, impl_trait_ref) ?;
0 commit comments