@@ -66,6 +66,10 @@ crate fn compare_impl_method<'tcx>(
66
66
{
67
67
return ;
68
68
}
69
+
70
+ if let Err ( ErrorReported ) = compare_const_param_types ( tcx, impl_m, trait_m, trait_item_span) {
71
+ return ;
72
+ }
69
73
}
70
74
71
75
fn compare_predicate_entailment < ' tcx > (
@@ -929,6 +933,68 @@ fn compare_synthetic_generics<'tcx>(
929
933
if error_found { Err ( ErrorReported ) } else { Ok ( ( ) ) }
930
934
}
931
935
936
+ fn compare_const_param_types < ' tcx > (
937
+ tcx : TyCtxt < ' tcx > ,
938
+ impl_m : & ty:: AssocItem ,
939
+ trait_m : & ty:: AssocItem ,
940
+ trait_item_span : Option < Span > ,
941
+ ) -> Result < ( ) , ErrorReported > {
942
+ let const_params_of = |def_id| {
943
+ tcx. generics_of ( def_id) . params . iter ( ) . filter_map ( |param| match param. kind {
944
+ GenericParamDefKind :: Const { .. } => Some ( param. def_id ) ,
945
+ _ => None ,
946
+ } )
947
+ } ;
948
+ let const_params_impl = const_params_of ( impl_m. def_id ) ;
949
+ let const_params_trait = const_params_of ( trait_m. def_id ) ;
950
+
951
+ for ( const_param_impl, const_param_trait) in iter:: zip ( const_params_impl, const_params_trait) {
952
+ let impl_ty = tcx. type_of ( const_param_impl) ;
953
+ let trait_ty = tcx. type_of ( const_param_trait) ;
954
+ if impl_ty != trait_ty {
955
+ let ( impl_span, impl_ident) = match tcx. hir ( ) . get_if_local ( const_param_impl) {
956
+ Some ( hir:: Node :: GenericParam ( hir:: GenericParam { span, name, .. } ) ) => (
957
+ span,
958
+ match name {
959
+ hir:: ParamName :: Plain ( ident) => Some ( ident) ,
960
+ _ => None ,
961
+ } ,
962
+ ) ,
963
+ other => bug ! (
964
+ "expected GenericParam, found {:?}" ,
965
+ other. map_or_else( || "nothing" . to_string( ) , |n| format!( "{:?}" , n) )
966
+ ) ,
967
+ } ;
968
+ let trait_span = match tcx. hir ( ) . get_if_local ( const_param_trait) {
969
+ Some ( hir:: Node :: GenericParam ( hir:: GenericParam { span, .. } ) ) => Some ( span) ,
970
+ _ => None ,
971
+ } ;
972
+ let mut err = struct_span_err ! (
973
+ tcx. sess,
974
+ * impl_span,
975
+ E0053 ,
976
+ "method `{}` has an incompatible const parameter type for trait" ,
977
+ trait_m. ident
978
+ ) ;
979
+ err. span_note (
980
+ trait_span. map_or_else ( || trait_item_span. unwrap_or ( * impl_span) , |span| * span) ,
981
+ & format ! (
982
+ "the const parameter{} has type `{}`, but the declaration \
983
+ in trait `{}` has type `{}`",
984
+ & impl_ident. map_or_else( || "" . to_string( ) , |ident| format!( " `{}`" , ident) ) ,
985
+ impl_ty,
986
+ tcx. def_path_str( trait_m. def_id) ,
987
+ trait_ty
988
+ ) ,
989
+ ) ;
990
+ err. emit ( ) ;
991
+ return Err ( ErrorReported ) ;
992
+ }
993
+ }
994
+
995
+ Ok ( ( ) )
996
+ }
997
+
932
998
crate fn compare_const_impl < ' tcx > (
933
999
tcx : TyCtxt < ' tcx > ,
934
1000
impl_c : & ty:: AssocItem ,
0 commit comments