@@ -700,6 +700,13 @@ impl<'tcx> DeadVisitor<'tcx> {
700700 . collect ( ) ;
701701
702702 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+ } ;
703710 let num = dead_codes. len ( ) ;
704711 let multiple = num > 6 ;
705712 let name_list = names. into ( ) ;
@@ -712,12 +719,12 @@ impl<'tcx> DeadVisitor<'tcx> {
712719
713720 let parent_info = if let Some ( parent_item) = parent_item {
714721 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 } )
721728 } else {
722729 None
723730 } ;
@@ -800,16 +807,7 @@ impl<'tcx> DeadVisitor<'tcx> {
800807 }
801808
802809 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) {
813811 return ;
814812 }
815813 match self . tcx . def_kind ( def_id) {
@@ -827,6 +825,18 @@ impl<'tcx> DeadVisitor<'tcx> {
827825 _ => { }
828826 }
829827 }
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+ }
830840}
831841
832842fn check_mod_deathness ( tcx : TyCtxt < ' _ > , module : LocalDefId ) {
@@ -836,6 +846,22 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
836846 let module_items = tcx. hir_module_items ( module) ;
837847
838848 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+
839865 if !live_symbols. contains ( & item. owner_id . def_id ) {
840866 let parent = tcx. local_parent ( item. owner_id . def_id ) ;
841867 if parent != module && !live_symbols. contains ( & parent) {
@@ -900,10 +926,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
900926 }
901927 }
902928
903- for impl_item in module_items. impl_items ( ) {
904- visitor. check_definition ( impl_item. owner_id . def_id ) ;
905- }
906-
907929 for foreign_item in module_items. foreign_items ( ) {
908930 visitor. check_definition ( foreign_item. owner_id . def_id ) ;
909931 }
0 commit comments