@@ -13,6 +13,7 @@ use rustc_hir::{Node, PatKind, TyKind};
13
13
use rustc_middle:: hir:: nested_filter;
14
14
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
15
15
use rustc_middle:: middle:: privacy;
16
+ use rustc_middle:: ty:: query:: Providers ;
16
17
use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
17
18
use rustc_session:: lint;
18
19
use rustc_span:: symbol:: { sym, Symbol } ;
@@ -52,7 +53,7 @@ struct MarkSymbolVisitor<'tcx> {
52
53
// maps from ADTs to ignored derived traits (e.g. Debug and Clone)
53
54
// and the span of their respective impl (i.e., part of the derive
54
55
// macro)
55
- ignored_derived_traits : FxHashMap < DefId , Vec < ( Span , DefId ) > > ,
56
+ ignored_derived_traits : FxHashMap < LocalDefId , Vec < ( DefId , DefId ) > > ,
56
57
}
57
58
58
59
impl < ' tcx > MarkSymbolVisitor < ' tcx > {
@@ -258,12 +259,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
258
259
if self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads) {
259
260
let trait_ref = self . tcx . impl_trait_ref ( impl_of) . unwrap ( ) ;
260
261
if let ty:: Adt ( adt_def, _) = trait_ref. self_ty ( ) . kind ( ) {
261
- let impl_span = self . tcx . def_span ( impl_of) ;
262
- if let Some ( v) = self . ignored_derived_traits . get_mut ( & adt_def. did ) {
263
- v. push ( ( impl_span, trait_of) ) ;
264
- } else {
262
+ if let Some ( adt_def_id) = adt_def. did . as_local ( ) {
265
263
self . ignored_derived_traits
266
- . insert ( adt_def. did , vec ! [ ( impl_span, trait_of) ] ) ;
264
+ . entry ( adt_def_id)
265
+ . or_default ( )
266
+ . push ( ( trait_of, impl_of) ) ;
267
267
}
268
268
}
269
269
return true ;
@@ -563,8 +563,8 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'tcx> {
563
563
564
564
fn create_and_seed_worklist < ' tcx > (
565
565
tcx : TyCtxt < ' tcx > ,
566
- access_levels : & privacy:: AccessLevels ,
567
566
) -> ( Vec < LocalDefId > , FxHashMap < LocalDefId , LocalDefId > ) {
567
+ let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
568
568
let worklist = access_levels
569
569
. map
570
570
. iter ( )
@@ -584,11 +584,11 @@ fn create_and_seed_worklist<'tcx>(
584
584
( life_seeder. worklist , life_seeder. struct_constructors )
585
585
}
586
586
587
- fn find_live < ' tcx > (
587
+ fn live_symbols_and_ignored_derived_traits < ' tcx > (
588
588
tcx : TyCtxt < ' tcx > ,
589
- access_levels : & privacy :: AccessLevels ,
590
- ) -> ( FxHashSet < LocalDefId > , FxHashMap < DefId , Vec < ( Span , DefId ) > > ) {
591
- let ( worklist, struct_constructors) = create_and_seed_worklist ( tcx, access_levels ) ;
589
+ ( ) : ( ) ,
590
+ ) -> ( FxHashSet < LocalDefId > , FxHashMap < LocalDefId , Vec < ( DefId , DefId ) > > ) {
591
+ let ( worklist, struct_constructors) = create_and_seed_worklist ( tcx) ;
592
592
let mut symbol_visitor = MarkSymbolVisitor {
593
593
worklist,
594
594
tcx,
@@ -608,8 +608,8 @@ fn find_live<'tcx>(
608
608
609
609
struct DeadVisitor < ' tcx > {
610
610
tcx : TyCtxt < ' tcx > ,
611
- live_symbols : FxHashSet < LocalDefId > ,
612
- ignored_derived_traits : FxHashMap < DefId , Vec < ( Span , DefId ) > > ,
611
+ live_symbols : & ' tcx FxHashSet < LocalDefId > ,
612
+ ignored_derived_traits : & ' tcx FxHashMap < LocalDefId , Vec < ( DefId , DefId ) > > ,
613
613
}
614
614
615
615
impl < ' tcx > DeadVisitor < ' tcx > {
@@ -682,12 +682,10 @@ impl<'tcx> DeadVisitor<'tcx> {
682
682
let hir = self . tcx . hir ( ) ;
683
683
if let Some ( encl_scope) = hir. get_enclosing_scope ( id) {
684
684
if let Some ( encl_def_id) = hir. opt_local_def_id ( encl_scope) {
685
- if let Some ( ign_traits) =
686
- self . ignored_derived_traits . get ( & encl_def_id. to_def_id ( ) )
687
- {
685
+ if let Some ( ign_traits) = self . ignored_derived_traits . get ( & encl_def_id) {
688
686
let traits_str = ign_traits
689
687
. iter ( )
690
- . map ( |( _ , t ) | format ! ( "`{}`" , self . tcx. item_name( * t ) ) )
688
+ . map ( |( trait_id , _ ) | format ! ( "`{}`" , self . tcx. item_name( * trait_id ) ) )
691
689
. collect :: < Vec < _ > > ( )
692
690
. join ( " and " ) ;
693
691
let plural_s = pluralize ! ( ign_traits. len( ) ) ;
@@ -703,7 +701,10 @@ impl<'tcx> DeadVisitor<'tcx> {
703
701
traits_str,
704
702
is_are
705
703
) ;
706
- let multispan = ign_traits. iter ( ) . map ( |( s, _) | * s) . collect :: < Vec < _ > > ( ) ;
704
+ let multispan = ign_traits
705
+ . iter ( )
706
+ . map ( |( _, impl_id) | self . tcx . def_span ( * impl_id) )
707
+ . collect :: < Vec < _ > > ( ) ;
707
708
err. span_note ( multispan, & msg) ;
708
709
}
709
710
}
@@ -761,6 +762,9 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
761
762
}
762
763
}
763
764
765
+ // This visitor should only visit a single module at a time.
766
+ fn visit_mod ( & mut self , _: & ' tcx hir:: Mod < ' tcx > , _: Span , _: hir:: HirId ) { }
767
+
764
768
fn visit_variant (
765
769
& mut self ,
766
770
variant : & ' tcx hir:: Variant < ' tcx > ,
@@ -836,9 +840,16 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
836
840
}
837
841
}
838
842
839
- pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
840
- let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
841
- let ( live_symbols, ignored_derived_traits) = find_live ( tcx, access_levels) ;
843
+ fn check_mod_deathness ( tcx : TyCtxt < ' _ > , module : LocalDefId ) {
844
+ let ( live_symbols, ignored_derived_traits) = tcx. live_symbols_and_ignored_derived_traits ( ( ) ) ;
842
845
let mut visitor = DeadVisitor { tcx, live_symbols, ignored_derived_traits } ;
843
- tcx. hir ( ) . walk_toplevel_module ( & mut visitor) ;
846
+ let ( module, _, module_id) = tcx. hir ( ) . get_module ( module) ;
847
+ // Do not use an ItemLikeVisitor since we may want to skip visiting some items
848
+ // when a surrounding one is warned against or `_`.
849
+ intravisit:: walk_mod ( & mut visitor, module, module_id) ;
850
+ }
851
+
852
+ pub ( crate ) fn provide ( providers : & mut Providers ) {
853
+ * providers =
854
+ Providers { live_symbols_and_ignored_derived_traits, check_mod_deathness, ..* providers } ;
844
855
}
0 commit comments