@@ -13,6 +13,7 @@ use rustc_hir::{Node, PatKind, TyKind};
1313use rustc_middle:: hir:: nested_filter;
1414use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
1515use rustc_middle:: middle:: privacy;
16+ use rustc_middle:: ty:: query:: Providers ;
1617use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
1718use rustc_session:: lint;
1819use rustc_span:: symbol:: { sym, Symbol } ;
@@ -52,7 +53,7 @@ struct MarkSymbolVisitor<'tcx> {
5253 // maps from ADTs to ignored derived traits (e.g. Debug and Clone)
5354 // and the span of their respective impl (i.e., part of the derive
5455 // macro)
55- ignored_derived_traits : FxHashMap < DefId , Vec < ( Span , DefId ) > > ,
56+ ignored_derived_traits : FxHashMap < LocalDefId , Vec < ( DefId , DefId ) > > ,
5657}
5758
5859impl < ' tcx > MarkSymbolVisitor < ' tcx > {
@@ -258,12 +259,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
258259 if self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads) {
259260 let trait_ref = self . tcx . impl_trait_ref ( impl_of) . unwrap ( ) ;
260261 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 ( ) {
265263 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) ) ;
267267 }
268268 }
269269 return true ;
@@ -563,8 +563,8 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'tcx> {
563563
564564fn create_and_seed_worklist < ' tcx > (
565565 tcx : TyCtxt < ' tcx > ,
566- access_levels : & privacy:: AccessLevels ,
567566) -> ( Vec < LocalDefId > , FxHashMap < LocalDefId , LocalDefId > ) {
567+ let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
568568 let worklist = access_levels
569569 . map
570570 . iter ( )
@@ -584,11 +584,11 @@ fn create_and_seed_worklist<'tcx>(
584584 ( life_seeder. worklist , life_seeder. struct_constructors )
585585}
586586
587- fn find_live < ' tcx > (
587+ fn live_symbols_and_ignored_derived_traits < ' tcx > (
588588 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) ;
592592 let mut symbol_visitor = MarkSymbolVisitor {
593593 worklist,
594594 tcx,
@@ -608,8 +608,8 @@ fn find_live<'tcx>(
608608
609609struct DeadVisitor < ' tcx > {
610610 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 ) > > ,
613613}
614614
615615impl < ' tcx > DeadVisitor < ' tcx > {
@@ -682,12 +682,10 @@ impl<'tcx> DeadVisitor<'tcx> {
682682 let hir = self . tcx . hir ( ) ;
683683 if let Some ( encl_scope) = hir. get_enclosing_scope ( id) {
684684 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) {
688686 let traits_str = ign_traits
689687 . iter ( )
690- . map ( |( _ , t ) | format ! ( "`{}`" , self . tcx. item_name( * t ) ) )
688+ . map ( |( trait_id , _ ) | format ! ( "`{}`" , self . tcx. item_name( * trait_id ) ) )
691689 . collect :: < Vec < _ > > ( )
692690 . join ( " and " ) ;
693691 let plural_s = pluralize ! ( ign_traits. len( ) ) ;
@@ -703,7 +701,10 @@ impl<'tcx> DeadVisitor<'tcx> {
703701 traits_str,
704702 is_are
705703 ) ;
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 < _ > > ( ) ;
707708 err. span_note ( multispan, & msg) ;
708709 }
709710 }
@@ -761,6 +762,9 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
761762 }
762763 }
763764
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+
764768 fn visit_variant (
765769 & mut self ,
766770 variant : & ' tcx hir:: Variant < ' tcx > ,
@@ -836,9 +840,16 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
836840 }
837841}
838842
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 ( ( ) ) ;
842845 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 } ;
844855}
0 commit comments