@@ -846,82 +846,128 @@ 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 ;
850
849
851
850
// Check existing impl methods to see if they are both present in trait
852
851
// and compatible with trait signature
853
852
for impl_item in impl_items {
854
- let ty_impl_item = ccx. tcx . impl_or_trait_item ( local_def ( impl_item. id ) ) ;
855
- let ty_trait_item = trait_items. iter ( )
856
- . find ( |ac| ac. name ( ) == ty_impl_item. name ( ) )
857
- . unwrap_or_else ( || {
858
- // This is checked by resolve
859
- tcx. sess . span_bug ( impl_item. span ,
860
- & format ! ( "impl-item `{}` is not a member of `{:?}`" ,
861
- token:: get_name( ty_impl_item. name( ) ) ,
862
- impl_trait_ref) ) ;
863
- } ) ;
864
853
match impl_item. node {
865
854
ast:: ConstImplItem ( ..) => {
866
- let impl_const = match ty_impl_item {
867
- ty:: ConstTraitItem ( ref cti) => cti,
868
- _ => tcx. sess . span_bug ( impl_item. span , "non-const impl-item for const" )
869
- } ;
855
+ let impl_const_def_id = local_def ( impl_item. id ) ;
856
+ let impl_const_ty = ccx. tcx . impl_or_trait_item ( impl_const_def_id) ;
870
857
871
858
// Find associated const definition.
872
- if let & ty:: ConstTraitItem ( ref trait_const) = ty_trait_item {
873
- compare_const_impl ( ccx. tcx ,
874
- & impl_const,
875
- impl_item. span ,
876
- trait_const,
877
- & * impl_trait_ref) ;
878
- } else {
879
- span_err ! ( tcx. sess, impl_item. span, E0323 ,
880
- "item `{}` is an associated const, \
881
- which doesn't match its trait `{:?}`",
882
- token:: get_name( impl_const. name) ,
883
- impl_trait_ref)
859
+ let opt_associated_const =
860
+ trait_items. iter ( )
861
+ . find ( |ac| ac. name ( ) == impl_const_ty. name ( ) ) ;
862
+ match opt_associated_const {
863
+ Some ( associated_const) => {
864
+ match ( associated_const, & impl_const_ty) {
865
+ ( & ty:: ConstTraitItem ( ref const_trait) ,
866
+ & ty:: ConstTraitItem ( ref const_impl) ) => {
867
+ compare_const_impl ( ccx. tcx ,
868
+ & const_impl,
869
+ impl_item. span ,
870
+ & const_trait,
871
+ & * impl_trait_ref) ;
872
+ }
873
+ _ => {
874
+ span_err ! ( tcx. sess, impl_item. span, E0323 ,
875
+ "item `{}` is an associated const, \
876
+ which doesn't match its trait `{:?}`",
877
+ token:: get_name( impl_const_ty. name( ) ) ,
878
+ impl_trait_ref)
879
+ }
880
+ }
881
+ }
882
+ None => {
883
+ // This is `span_bug` as it should have already been
884
+ // caught in resolve.
885
+ tcx. sess . span_bug (
886
+ impl_item. span ,
887
+ & format ! (
888
+ "associated const `{}` is not a member of \
889
+ trait `{:?}`",
890
+ token:: get_name( impl_const_ty. name( ) ) ,
891
+ impl_trait_ref) ) ;
892
+ }
884
893
}
885
894
}
886
895
ast:: MethodImplItem ( ref sig, ref body) => {
887
896
check_trait_fn_not_const ( ccx, impl_item. span , sig. constness ) ;
888
897
889
- let impl_method = match ty_impl_item {
890
- ty:: MethodTraitItem ( ref mti) => mti,
891
- _ => tcx. sess . span_bug ( impl_item. span , "non-method impl-item for method" )
892
- } ;
893
-
894
- if let & ty:: MethodTraitItem ( ref trait_method) = ty_trait_item {
895
- compare_impl_method ( ccx. tcx ,
896
- & impl_method,
897
- impl_item. span ,
898
- body. id ,
899
- & trait_method,
900
- & impl_trait_ref) ;
901
- } else {
902
- span_err ! ( tcx. sess, impl_item. span, E0324 ,
903
- "item `{}` is an associated method, \
904
- which doesn't match its trait `{:?}`",
905
- token:: get_name( impl_method. name) ,
906
- impl_trait_ref)
898
+ let impl_method_def_id = local_def ( impl_item. id ) ;
899
+ let impl_item_ty = ccx. tcx . impl_or_trait_item ( impl_method_def_id) ;
900
+
901
+ // If this is an impl of a trait method, find the
902
+ // corresponding method definition in the trait.
903
+ let opt_trait_method_ty =
904
+ trait_items. iter ( )
905
+ . find ( |ti| ti. name ( ) == impl_item_ty. name ( ) ) ;
906
+ match opt_trait_method_ty {
907
+ Some ( trait_method_ty) => {
908
+ match ( trait_method_ty, & impl_item_ty) {
909
+ ( & ty:: MethodTraitItem ( ref trait_method_ty) ,
910
+ & ty:: MethodTraitItem ( ref impl_method_ty) ) => {
911
+ compare_impl_method ( ccx. tcx ,
912
+ & * * impl_method_ty,
913
+ impl_item. span ,
914
+ body. id ,
915
+ & * * trait_method_ty,
916
+ & * impl_trait_ref) ;
917
+ }
918
+ _ => {
919
+ span_err ! ( tcx. sess, impl_item. span, E0324 ,
920
+ "item `{}` is an associated method, \
921
+ which doesn't match its trait `{:?}`",
922
+ token:: get_name( impl_item_ty. name( ) ) ,
923
+ impl_trait_ref)
924
+ }
925
+ }
926
+ }
927
+ None => {
928
+ // This is span_bug as it should have already been
929
+ // caught in resolve.
930
+ tcx. sess . span_bug (
931
+ impl_item. span ,
932
+ & format ! ( "method `{}` is not a member of trait `{:?}`" ,
933
+ token:: get_name( impl_item_ty. name( ) ) ,
934
+ impl_trait_ref) ) ;
935
+ }
907
936
}
908
937
}
909
938
ast:: TypeImplItem ( _) => {
910
- let impl_type = match ty_impl_item {
911
- ty:: TypeTraitItem ( ref tti) => tti,
912
- _ => tcx. sess . span_bug ( impl_item. span , "non-type impl-item for type" )
913
- } ;
914
-
915
- if let & ty:: TypeTraitItem ( ref at) = ty_trait_item {
916
- if let Some ( _) = at. ty {
917
- overridden_associated_type = Some ( impl_item) ;
939
+ let typedef_def_id = local_def ( impl_item. id ) ;
940
+ let typedef_ty = ccx. tcx . impl_or_trait_item ( typedef_def_id) ;
941
+
942
+ // If this is an impl of an associated type, find the
943
+ // corresponding type definition in the trait.
944
+ let opt_associated_type =
945
+ trait_items. iter ( )
946
+ . find ( |ti| ti. name ( ) == typedef_ty. name ( ) ) ;
947
+ match opt_associated_type {
948
+ Some ( associated_type) => {
949
+ match ( associated_type, & typedef_ty) {
950
+ ( & ty:: TypeTraitItem ( _) , & ty:: TypeTraitItem ( _) ) => { }
951
+ _ => {
952
+ span_err ! ( tcx. sess, impl_item. span, E0325 ,
953
+ "item `{}` is an associated type, \
954
+ which doesn't match its trait `{:?}`",
955
+ token:: get_name( typedef_ty. name( ) ) ,
956
+ impl_trait_ref)
957
+ }
958
+ }
959
+ }
960
+ None => {
961
+ // This is `span_bug` as it should have already been
962
+ // caught in resolve.
963
+ tcx. sess . span_bug (
964
+ impl_item. span ,
965
+ & format ! (
966
+ "associated type `{}` is not a member of \
967
+ trait `{:?}`",
968
+ token:: get_name( typedef_ty. name( ) ) ,
969
+ impl_trait_ref) ) ;
918
970
}
919
- } else {
920
- span_err ! ( tcx. sess, impl_item. span, E0325 ,
921
- "item `{}` is an associated type, \
922
- which doesn't match its trait `{:?}`",
923
- token:: get_name( impl_type. name) ,
924
- impl_trait_ref)
925
971
}
926
972
}
927
973
ast:: MacImplItem ( _) => tcx. sess . span_bug ( impl_item. span ,
@@ -933,8 +979,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
933
979
let provided_methods = tcx. provided_trait_methods ( impl_trait_ref. def_id ) ;
934
980
let associated_consts = tcx. associated_consts ( impl_trait_ref. def_id ) ;
935
981
let mut missing_items = Vec :: new ( ) ;
936
- let mut invalidated_items = Vec :: new ( ) ;
937
- let associated_type_overridden = overridden_associated_type. is_some ( ) ;
938
982
for trait_item in trait_items. iter ( ) {
939
983
match * trait_item {
940
984
ty:: ConstTraitItem ( ref associated_const) => {
@@ -949,12 +993,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
949
993
let is_provided =
950
994
associated_consts. iter ( ) . any ( |ac| ac. default . is_some ( ) &&
951
995
ac. 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
- }
996
+ if !is_implemented && !is_provided {
997
+ missing_items. push ( format ! ( "`{}`" ,
998
+ token:: get_name( associated_const. name) ) ) ;
958
999
}
959
1000
}
960
1001
ty:: MethodTraitItem ( ref trait_method) => {
@@ -969,12 +1010,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
969
1010
} ) ;
970
1011
let is_provided =
971
1012
provided_methods. iter ( ) . any ( |m| m. 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
- }
1013
+ if !is_implemented && !is_provided {
1014
+ missing_items. push ( format ! ( "`{}`" , token:: get_name( trait_method. name) ) ) ;
978
1015
}
979
1016
}
980
1017
ty:: TypeTraitItem ( ref associated_type) => {
@@ -987,34 +1024,17 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
987
1024
}
988
1025
} ) ;
989
1026
let is_provided = associated_type. ty . is_some ( ) ;
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
- }
1027
+ if !is_implemented && !is_provided {
1028
+ missing_items. push ( format ! ( "`{}`" , token:: get_name( associated_type. name) ) ) ;
996
1029
}
997
1030
}
998
1031
}
999
1032
}
1000
1033
1001
1034
if !missing_items. is_empty ( ) {
1002
1035
span_err ! ( tcx. sess, impl_span, E0046 ,
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( "`, `" ) )
1036
+ "not all trait items implemented, missing: {}" ,
1037
+ missing_items. connect( ", " ) ) ;
1018
1038
}
1019
1039
}
1020
1040
0 commit comments