4
4
// is dead.
5
5
6
6
use hir:: def_id:: { LocalDefIdMap , LocalDefIdSet } ;
7
- use itertools:: Itertools ;
8
7
use rustc_data_structures:: unord:: UnordSet ;
9
8
use rustc_errors:: MultiSpan ;
10
9
use rustc_hir as hir;
@@ -16,7 +15,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
16
15
use rustc_middle:: middle:: privacy:: Level ;
17
16
use rustc_middle:: query:: Providers ;
18
17
use 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 } ;
20
20
use rustc_span:: symbol:: { sym, Symbol } ;
21
21
use rustc_target:: abi:: FieldIdx ;
22
22
use std:: mem;
@@ -762,7 +762,7 @@ struct DeadVisitor<'tcx> {
762
762
}
763
763
764
764
enum ShouldWarnAboutField {
765
- Yes ( bool ) , // positional?
765
+ Yes ,
766
766
No ,
767
767
}
768
768
@@ -784,7 +784,12 @@ impl<'tcx> DeadVisitor<'tcx> {
784
784
{
785
785
return ShouldWarnAboutField :: No ;
786
786
}
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
788
793
}
789
794
790
795
// # Panics
@@ -795,38 +800,33 @@ impl<'tcx> DeadVisitor<'tcx> {
795
800
// since those methods group by lint level before calling this method.
796
801
fn lint_at_single_level (
797
802
& self ,
798
- dead_codes : & [ LocalDefId ] ,
803
+ dead_codes : & [ & DeadItem ] ,
799
804
participle : & str ,
800
805
parent_item : Option < LocalDefId > ,
801
- is_positional : bool ,
806
+ lint : & ' static Lint ,
802
807
) {
803
- let Some ( & first_id ) = dead_codes. first ( ) else {
808
+ let Some ( & first_item ) = dead_codes. first ( ) else {
804
809
return ;
805
810
} ;
806
811
let tcx = self . tcx ;
807
812
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) ) ;
815
815
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 ( ) ;
818
817
let spans: Vec < _ > = dead_codes
819
818
. 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 ) ,
823
822
} )
824
823
. collect ( ) ;
825
824
826
- let descr = tcx. def_descr ( first_id . to_def_id ( ) ) ;
825
+ let descr = tcx. def_descr ( first_item . def_id . to_def_id ( ) ) ;
827
826
// `impl` blocks are "batched" and (unlike other batching) might
828
827
// 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
+ {
830
830
"associated item"
831
831
} else {
832
832
descr
@@ -835,12 +835,6 @@ impl<'tcx> DeadVisitor<'tcx> {
835
835
let multiple = num > 6 ;
836
836
let name_list = names. into ( ) ;
837
837
838
- let lint = if is_positional {
839
- lint:: builtin:: UNUSED_TUPLE_STRUCT_FIELDS
840
- } else {
841
- lint:: builtin:: DEAD_CODE
842
- } ;
843
-
844
838
let parent_info = if let Some ( parent_item) = parent_item {
845
839
let parent_descr = tcx. def_descr ( parent_item. to_def_id ( ) ) ;
846
840
let span = if let DefKind :: Impl { .. } = tcx. def_kind ( parent_item) {
@@ -853,7 +847,7 @@ impl<'tcx> DeadVisitor<'tcx> {
853
847
None
854
848
} ;
855
849
856
- let encl_def_id = parent_item. unwrap_or ( first_id ) ;
850
+ let encl_def_id = parent_item. unwrap_or ( first_item . def_id ) ;
857
851
let ignored_derived_impls =
858
852
if let Some ( ign_traits) = self . ignored_derived_traits . get ( & encl_def_id) {
859
853
let trait_list = ign_traits
@@ -870,7 +864,7 @@ impl<'tcx> DeadVisitor<'tcx> {
870
864
None
871
865
} ;
872
866
873
- let diag = if is_positional {
867
+ let diag = if LintId :: of ( lint ) == LintId :: of ( UNUSED_TUPLE_STRUCT_FIELDS ) {
874
868
MultipleDeadCodes :: UnusedTupleStructFields {
875
869
multiple,
876
870
num,
@@ -893,15 +887,16 @@ impl<'tcx> DeadVisitor<'tcx> {
893
887
}
894
888
} ;
895
889
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) ;
897
892
}
898
893
899
894
fn warn_multiple (
900
895
& self ,
901
896
def_id : LocalDefId ,
902
897
participle : & str ,
903
898
dead_codes : Vec < DeadItem > ,
904
- is_positional : bool ,
899
+ lint : & ' static Lint ,
905
900
) {
906
901
let mut dead_codes = dead_codes
907
902
. iter ( )
@@ -911,18 +906,18 @@ impl<'tcx> DeadVisitor<'tcx> {
911
906
return ;
912
907
}
913
908
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) ;
921
911
}
922
912
}
923
913
924
914
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 ) ;
926
921
}
927
922
928
923
fn check_definition ( & mut self , def_id : LocalDefId ) {
@@ -969,13 +964,12 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
969
964
let def_id = item. id . owner_id . def_id ;
970
965
if !visitor. is_live_code ( def_id) {
971
966
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) ;
974
968
975
969
dead_items. push ( DeadItem { def_id, name, level } )
976
970
}
977
971
}
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 ) ;
979
973
}
980
974
981
975
if !live_symbols. contains ( & item. owner_id . def_id ) {
@@ -997,43 +991,32 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
997
991
let def_id = variant. def_id . expect_local ( ) ;
998
992
if !live_symbols. contains ( & def_id) {
999
993
// 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) ;
1002
995
dead_variants. push ( DeadItem { def_id, name : variant. name , level } ) ;
1003
996
continue ;
1004
997
}
1005
998
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 } ;
1007
1003
let dead_fields = variant
1008
1004
. fields
1009
1005
. iter ( )
1010
1006
. filter_map ( |field| {
1011
1007
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) ;
1027
1010
Some ( DeadItem { def_id, name : field. name , level } )
1028
1011
} else {
1029
1012
None
1030
1013
}
1031
1014
} )
1032
1015
. collect ( ) ;
1033
- visitor. warn_multiple ( def_id, "read" , dead_fields, is_positional ) ;
1016
+ visitor. warn_multiple ( def_id, "read" , dead_fields, lint ) ;
1034
1017
}
1035
1018
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 ) ;
1037
1020
}
1038
1021
}
1039
1022
0 commit comments