44// is dead.
55
66use hir:: def_id:: { LocalDefIdMap , LocalDefIdSet } ;
7- use itertools:: Itertools ;
87use rustc_data_structures:: unord:: UnordSet ;
98use rustc_errors:: MultiSpan ;
109use rustc_hir as hir;
@@ -16,7 +15,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1615use rustc_middle:: middle:: privacy:: Level ;
1716use rustc_middle:: query:: Providers ;
1817use rustc_middle:: ty:: { self , TyCtxt } ;
19- use rustc_session:: lint;
18+ use rustc_session:: lint:: builtin:: { DEAD_CODE , UNUSED_TUPLE_STRUCT_FIELDS } ;
19+ use rustc_session:: lint:: { self , Lint , LintId } ;
2020use rustc_span:: symbol:: { sym, Symbol } ;
2121use rustc_target:: abi:: FieldIdx ;
2222use std:: mem;
@@ -762,7 +762,7 @@ struct DeadVisitor<'tcx> {
762762}
763763
764764enum ShouldWarnAboutField {
765- Yes ( bool ) , // positional?
765+ Yes ,
766766 No ,
767767}
768768
@@ -784,7 +784,12 @@ impl<'tcx> DeadVisitor<'tcx> {
784784 {
785785 return ShouldWarnAboutField :: No ;
786786 }
787- ShouldWarnAboutField :: Yes ( is_positional)
787+ ShouldWarnAboutField :: Yes
788+ }
789+
790+ fn def_lint_level ( & self , lint : & ' static Lint , id : LocalDefId ) -> lint:: Level {
791+ let hir_id = self . tcx . local_def_id_to_hir_id ( id) ;
792+ self . tcx . lint_level_at_node ( lint, hir_id) . 0
788793 }
789794
790795 // # Panics
@@ -795,38 +800,33 @@ impl<'tcx> DeadVisitor<'tcx> {
795800 // since those methods group by lint level before calling this method.
796801 fn lint_at_single_level (
797802 & self ,
798- dead_codes : & [ LocalDefId ] ,
803+ dead_codes : & [ & DeadItem ] ,
799804 participle : & str ,
800805 parent_item : Option < LocalDefId > ,
801- is_positional : bool ,
806+ lint : & ' static Lint ,
802807 ) {
803- let Some ( & first_id ) = dead_codes. first ( ) else {
808+ let Some ( & first_item ) = dead_codes. first ( ) else {
804809 return ;
805810 } ;
806811 let tcx = self . tcx ;
807812
808- let first_hir_id = tcx. local_def_id_to_hir_id ( first_id) ;
809- let first_lint_level = tcx. lint_level_at_node ( lint:: builtin:: DEAD_CODE , first_hir_id) . 0 ;
810- assert ! ( dead_codes. iter( ) . skip( 1 ) . all( |id| {
811- let hir_id = tcx. local_def_id_to_hir_id( * id) ;
812- let level = tcx. lint_level_at_node( lint:: builtin:: DEAD_CODE , hir_id) . 0 ;
813- level == first_lint_level
814- } ) ) ;
813+ let first_lint_level = first_item. level ;
814+ assert ! ( dead_codes. iter( ) . skip( 1 ) . all( |item| item. level == first_lint_level) ) ;
815815
816- let names: Vec < _ > =
817- dead_codes. iter ( ) . map ( |& def_id| tcx. item_name ( def_id. to_def_id ( ) ) ) . collect ( ) ;
816+ let names: Vec < _ > = dead_codes. iter ( ) . map ( |item| item. name ) . collect ( ) ;
818817 let spans: Vec < _ > = dead_codes
819818 . iter ( )
820- . map ( |& def_id | match tcx. def_ident_span ( def_id) {
821- Some ( s) => s. with_ctxt ( tcx. def_span ( def_id) . ctxt ( ) ) ,
822- None => tcx. def_span ( def_id) ,
819+ . map ( |item | match tcx. def_ident_span ( item . def_id ) {
820+ Some ( s) => s. with_ctxt ( tcx. def_span ( item . def_id ) . ctxt ( ) ) ,
821+ None => tcx. def_span ( item . def_id ) ,
823822 } )
824823 . collect ( ) ;
825824
826- let descr = tcx. def_descr ( first_id . to_def_id ( ) ) ;
825+ let descr = tcx. def_descr ( first_item . def_id . to_def_id ( ) ) ;
827826 // `impl` blocks are "batched" and (unlike other batching) might
828827 // contain different kinds of associated items.
829- let descr = if dead_codes. iter ( ) . any ( |did| tcx. def_descr ( did. to_def_id ( ) ) != descr) {
828+ let descr = if dead_codes. iter ( ) . any ( |item| tcx. def_descr ( item. def_id . to_def_id ( ) ) != descr)
829+ {
830830 "associated item"
831831 } else {
832832 descr
@@ -835,12 +835,6 @@ impl<'tcx> DeadVisitor<'tcx> {
835835 let multiple = num > 6 ;
836836 let name_list = names. into ( ) ;
837837
838- let lint = if is_positional {
839- lint:: builtin:: UNUSED_TUPLE_STRUCT_FIELDS
840- } else {
841- lint:: builtin:: DEAD_CODE
842- } ;
843-
844838 let parent_info = if let Some ( parent_item) = parent_item {
845839 let parent_descr = tcx. def_descr ( parent_item. to_def_id ( ) ) ;
846840 let span = if let DefKind :: Impl { .. } = tcx. def_kind ( parent_item) {
@@ -853,7 +847,7 @@ impl<'tcx> DeadVisitor<'tcx> {
853847 None
854848 } ;
855849
856- let encl_def_id = parent_item. unwrap_or ( first_id ) ;
850+ let encl_def_id = parent_item. unwrap_or ( first_item . def_id ) ;
857851 let ignored_derived_impls =
858852 if let Some ( ign_traits) = self . ignored_derived_traits . get ( & encl_def_id) {
859853 let trait_list = ign_traits
@@ -870,7 +864,7 @@ impl<'tcx> DeadVisitor<'tcx> {
870864 None
871865 } ;
872866
873- let diag = if is_positional {
867+ let diag = if LintId :: of ( lint ) == LintId :: of ( UNUSED_TUPLE_STRUCT_FIELDS ) {
874868 MultipleDeadCodes :: UnusedTupleStructFields {
875869 multiple,
876870 num,
@@ -893,15 +887,16 @@ impl<'tcx> DeadVisitor<'tcx> {
893887 }
894888 } ;
895889
896- self . tcx . emit_spanned_lint ( lint, first_hir_id, MultiSpan :: from_spans ( spans) , diag) ;
890+ let hir_id = tcx. local_def_id_to_hir_id ( first_item. def_id ) ;
891+ self . tcx . emit_spanned_lint ( lint, hir_id, MultiSpan :: from_spans ( spans) , diag) ;
897892 }
898893
899894 fn warn_multiple (
900895 & self ,
901896 def_id : LocalDefId ,
902897 participle : & str ,
903898 dead_codes : Vec < DeadItem > ,
904- is_positional : bool ,
899+ lint : & ' static Lint ,
905900 ) {
906901 let mut dead_codes = dead_codes
907902 . iter ( )
@@ -911,18 +906,18 @@ impl<'tcx> DeadVisitor<'tcx> {
911906 return ;
912907 }
913908 dead_codes. sort_by_key ( |v| v. level ) ;
914- for ( _, group) in & dead_codes. into_iter ( ) . group_by ( |v| v. level ) {
915- self . lint_at_single_level (
916- & group. map ( |v| v. def_id ) . collect :: < Vec < _ > > ( ) ,
917- participle,
918- Some ( def_id) ,
919- is_positional,
920- ) ;
909+ for group in dead_codes[ ..] . group_by ( |a, b| a. level == b. level ) {
910+ self . lint_at_single_level ( & group, participle, Some ( def_id) , lint) ;
921911 }
922912 }
923913
924914 fn warn_dead_code ( & mut self , id : LocalDefId , participle : & str ) {
925- self . lint_at_single_level ( & [ id] , participle, None , false ) ;
915+ let item = DeadItem {
916+ def_id : id,
917+ name : self . tcx . item_name ( id. to_def_id ( ) ) ,
918+ level : self . def_lint_level ( DEAD_CODE , id) ,
919+ } ;
920+ self . lint_at_single_level ( & [ & item] , participle, None , DEAD_CODE ) ;
926921 }
927922
928923 fn check_definition ( & mut self , def_id : LocalDefId ) {
@@ -969,13 +964,12 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
969964 let def_id = item. id . owner_id . def_id ;
970965 if !visitor. is_live_code ( def_id) {
971966 let name = tcx. item_name ( def_id. to_def_id ( ) ) ;
972- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
973- let level = tcx. lint_level_at_node ( lint:: builtin:: DEAD_CODE , hir_id) . 0 ;
967+ let level = visitor. def_lint_level ( DEAD_CODE , def_id) ;
974968
975969 dead_items. push ( DeadItem { def_id, name, level } )
976970 }
977971 }
978- visitor. warn_multiple ( item. owner_id . def_id , "used" , dead_items, false ) ;
972+ visitor. warn_multiple ( item. owner_id . def_id , "used" , dead_items, DEAD_CODE ) ;
979973 }
980974
981975 if !live_symbols. contains ( & item. owner_id . def_id ) {
@@ -997,43 +991,32 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
997991 let def_id = variant. def_id . expect_local ( ) ;
998992 if !live_symbols. contains ( & def_id) {
999993 // Record to group diagnostics.
1000- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
1001- let level = tcx. lint_level_at_node ( lint:: builtin:: DEAD_CODE , hir_id) . 0 ;
994+ let level = visitor. def_lint_level ( DEAD_CODE , def_id) ;
1002995 dead_variants. push ( DeadItem { def_id, name : variant. name , level } ) ;
1003996 continue ;
1004997 }
1005998
1006- let mut is_positional = false ;
999+ let is_positional = variant. fields . raw . first ( ) . map_or ( false , |field| {
1000+ field. name . as_str ( ) . starts_with ( |c : char | c. is_ascii_digit ( ) )
1001+ } ) ;
1002+ let lint = if is_positional { UNUSED_TUPLE_STRUCT_FIELDS } else { DEAD_CODE } ;
10071003 let dead_fields = variant
10081004 . fields
10091005 . iter ( )
10101006 . filter_map ( |field| {
10111007 let def_id = field. did . expect_local ( ) ;
1012- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
1013- if let ShouldWarnAboutField :: Yes ( is_pos) =
1014- visitor. should_warn_about_field ( field)
1015- {
1016- let level = tcx
1017- . lint_level_at_node (
1018- if is_pos {
1019- is_positional = true ;
1020- lint:: builtin:: UNUSED_TUPLE_STRUCT_FIELDS
1021- } else {
1022- lint:: builtin:: DEAD_CODE
1023- } ,
1024- hir_id,
1025- )
1026- . 0 ;
1008+ if let ShouldWarnAboutField :: Yes = visitor. should_warn_about_field ( field) {
1009+ let level = visitor. def_lint_level ( lint, def_id) ;
10271010 Some ( DeadItem { def_id, name : field. name , level } )
10281011 } else {
10291012 None
10301013 }
10311014 } )
10321015 . collect ( ) ;
1033- visitor. warn_multiple ( def_id, "read" , dead_fields, is_positional ) ;
1016+ visitor. warn_multiple ( def_id, "read" , dead_fields, lint ) ;
10341017 }
10351018
1036- visitor. warn_multiple ( item. owner_id . def_id , "constructed" , dead_variants, false ) ;
1019+ visitor. warn_multiple ( item. owner_id . def_id , "constructed" , dead_variants, DEAD_CODE ) ;
10371020 }
10381021 }
10391022
0 commit comments