@@ -846,6 +846,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
846
846
// Locate trait methods
847
847
let tcx = ccx. tcx ;
848
848
let trait_items = tcx. trait_items ( impl_trait_ref. def_id ) ;
849
+ let mut overridden_associated_type = None ;
849
850
850
851
// Check existing impl methods to see if they are both present in trait
851
852
// and compatible with trait signature
@@ -911,8 +912,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
911
912
_ => tcx. sess . span_bug ( impl_item. span , "non-type impl-item for type" )
912
913
} ;
913
914
914
- if let & ty:: TypeTraitItem ( ..) = ty_trait_item {
915
- // ...
915
+ if let & ty:: TypeTraitItem ( ref at) = ty_trait_item {
916
+ if let Some ( _) = at. ty {
917
+ overridden_associated_type = Some ( impl_item) ;
918
+ }
916
919
} else {
917
920
span_err ! ( tcx. sess, impl_item. span, E0325 ,
918
921
"item `{}` is an associated type, \
@@ -930,6 +933,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
930
933
let provided_methods = tcx. provided_trait_methods ( impl_trait_ref. def_id ) ;
931
934
let associated_consts = tcx. associated_consts ( impl_trait_ref. def_id ) ;
932
935
let mut missing_items = Vec :: new ( ) ;
936
+ let mut invalidated_items = Vec :: new ( ) ;
937
+ let associated_type_overridden = overridden_associated_type. is_some ( ) ;
933
938
for trait_item in trait_items. iter ( ) {
934
939
match * trait_item {
935
940
ty:: ConstTraitItem ( ref associated_const) => {
@@ -944,9 +949,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
944
949
let is_provided =
945
950
associated_consts. iter ( ) . any ( |ac| ac. default . is_some ( ) &&
946
951
ac. name == associated_const. name ) ;
947
- if !is_implemented && !is_provided {
948
- missing_items. push ( format ! ( "`{}`" ,
949
- token:: get_name( associated_const. name) ) ) ;
952
+ if !is_implemented {
953
+ if !is_provided {
954
+ missing_items. push ( associated_const. name ) ;
955
+ } else if associated_type_overridden {
956
+ invalidated_items. push ( associated_const. name ) ;
957
+ }
950
958
}
951
959
}
952
960
ty:: MethodTraitItem ( ref trait_method) => {
@@ -961,8 +969,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
961
969
} ) ;
962
970
let is_provided =
963
971
provided_methods. iter ( ) . any ( |m| m. name == trait_method. name ) ;
964
- if !is_implemented && !is_provided {
965
- missing_items. push ( format ! ( "`{}`" , token:: get_name( trait_method. name) ) ) ;
972
+ if !is_implemented {
973
+ if !is_provided {
974
+ missing_items. push ( trait_method. name ) ;
975
+ } else if associated_type_overridden {
976
+ invalidated_items. push ( trait_method. name ) ;
977
+ }
966
978
}
967
979
}
968
980
ty:: TypeTraitItem ( ref associated_type) => {
@@ -975,17 +987,34 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
975
987
}
976
988
} ) ;
977
989
let is_provided = associated_type. ty . is_some ( ) ;
978
- if !is_implemented && !is_provided {
979
- missing_items. push ( format ! ( "`{}`" , token:: get_name( associated_type. name) ) ) ;
990
+ if !is_implemented {
991
+ if !is_provided {
992
+ missing_items. push ( associated_type. name ) ;
993
+ } else if associated_type_overridden {
994
+ invalidated_items. push ( associated_type. name ) ;
995
+ }
980
996
}
981
997
}
982
998
}
983
999
}
984
1000
985
1001
if !missing_items. is_empty ( ) {
986
1002
span_err ! ( tcx. sess, impl_span, E0046 ,
987
- "not all trait items implemented, missing: {}" ,
988
- missing_items. connect( ", " ) ) ;
1003
+ "not all trait items implemented, missing: `{}`" ,
1004
+ missing_items. iter( )
1005
+ . map( <ast:: Name >:: as_str)
1006
+ . collect:: <Vec <_>>( ) . connect( "`, `" ) )
1007
+ }
1008
+
1009
+ if !invalidated_items. is_empty ( ) {
1010
+ let invalidator = overridden_associated_type. unwrap ( ) ;
1011
+ span_err ! ( tcx. sess, invalidator. span, E0399 ,
1012
+ "the following trait items need to be reimplemented \
1013
+ as `{}` was overridden: `{}`",
1014
+ invalidator. ident. as_str( ) ,
1015
+ invalidated_items. iter( )
1016
+ . map( <ast:: Name >:: as_str)
1017
+ . collect:: <Vec <_>>( ) . connect( "`, `" ) )
989
1018
}
990
1019
}
991
1020
0 commit comments