@@ -700,6 +700,13 @@ impl<'tcx> DeadVisitor<'tcx> {
700
700
. collect ( ) ;
701
701
702
702
let descr = tcx. def_descr ( first_id. to_def_id ( ) ) ;
703
+ // `impl` blocks are "batched" and (unlike other batching) might
704
+ // contain different kinds of associated items.
705
+ let descr = if dead_codes. iter ( ) . any ( |did| tcx. def_descr ( did. to_def_id ( ) ) != descr) {
706
+ "associated item"
707
+ } else {
708
+ descr
709
+ } ;
703
710
let num = dead_codes. len ( ) ;
704
711
let multiple = num > 6 ;
705
712
let name_list = names. into ( ) ;
@@ -712,12 +719,12 @@ impl<'tcx> DeadVisitor<'tcx> {
712
719
713
720
let parent_info = if let Some ( parent_item) = parent_item {
714
721
let parent_descr = tcx. def_descr ( parent_item. to_def_id ( ) ) ;
715
- Some ( ParentInfo {
716
- num ,
717
- descr ,
718
- parent_descr ,
719
- span : tcx . def_ident_span ( parent_item ) . unwrap ( ) ,
720
- } )
722
+ let span = if let DefKind :: Impl { .. } = tcx . def_kind ( parent_item ) {
723
+ tcx . def_span ( parent_item )
724
+ } else {
725
+ tcx . def_ident_span ( parent_item ) . unwrap ( )
726
+ } ;
727
+ Some ( ParentInfo { num , descr , parent_descr , span } )
721
728
} else {
722
729
None
723
730
} ;
@@ -800,16 +807,7 @@ impl<'tcx> DeadVisitor<'tcx> {
800
807
}
801
808
802
809
fn check_definition ( & mut self , def_id : LocalDefId ) {
803
- if self . live_symbols . contains ( & def_id) {
804
- return ;
805
- }
806
- if has_allow_dead_code_or_lang_attr ( self . tcx , def_id) {
807
- return ;
808
- }
809
- let Some ( name) = self . tcx . opt_item_name ( def_id. to_def_id ( ) ) else {
810
- return
811
- } ;
812
- if name. as_str ( ) . starts_with ( '_' ) {
810
+ if self . is_live_code ( def_id) {
813
811
return ;
814
812
}
815
813
match self . tcx . def_kind ( def_id) {
@@ -827,6 +825,18 @@ impl<'tcx> DeadVisitor<'tcx> {
827
825
_ => { }
828
826
}
829
827
}
828
+
829
+ fn is_live_code ( & self , def_id : LocalDefId ) -> bool {
830
+ // if we cannot get a name for the item, then we just assume that it is
831
+ // live. I mean, we can't really emit a lint.
832
+ let Some ( name) = self . tcx . opt_item_name ( def_id. to_def_id ( ) ) else {
833
+ return true ;
834
+ } ;
835
+
836
+ self . live_symbols . contains ( & def_id)
837
+ || has_allow_dead_code_or_lang_attr ( self . tcx , def_id)
838
+ || name. as_str ( ) . starts_with ( '_' )
839
+ }
830
840
}
831
841
832
842
fn check_mod_deathness ( tcx : TyCtxt < ' _ > , module : LocalDefId ) {
@@ -836,6 +846,22 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
836
846
let module_items = tcx. hir_module_items ( module) ;
837
847
838
848
for item in module_items. items ( ) {
849
+ if let hir:: ItemKind :: Impl ( impl_item) = tcx. hir ( ) . item ( item) . kind {
850
+ let mut dead_items = Vec :: new ( ) ;
851
+ for item in impl_item. items {
852
+ let did = item. id . owner_id . def_id ;
853
+ if !visitor. is_live_code ( did) {
854
+ dead_items. push ( did)
855
+ }
856
+ }
857
+ visitor. warn_multiple_dead_codes (
858
+ & dead_items,
859
+ "used" ,
860
+ Some ( item. owner_id . def_id ) ,
861
+ false ,
862
+ ) ;
863
+ }
864
+
839
865
if !live_symbols. contains ( & item. owner_id . def_id ) {
840
866
let parent = tcx. local_parent ( item. owner_id . def_id ) ;
841
867
if parent != module && !live_symbols. contains ( & parent) {
@@ -900,10 +926,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
900
926
}
901
927
}
902
928
903
- for impl_item in module_items. impl_items ( ) {
904
- visitor. check_definition ( impl_item. owner_id . def_id ) ;
905
- }
906
-
907
929
for foreign_item in module_items. foreign_items ( ) {
908
930
visitor. check_definition ( foreign_item. owner_id . def_id ) ;
909
931
}
0 commit comments