@@ -26,9 +26,9 @@ use rustc_errors::{MultiSpan, listify};
2626use rustc_hir as hir;
2727use rustc_hir:: attrs:: AttributeKind ;
2828use rustc_hir:: def:: { DefKind , Res } ;
29- use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId , LocalModDefId } ;
29+ use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
3030use rustc_hir:: intravisit:: { self , InferKind , Visitor } ;
31- use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , PatKind , find_attr} ;
31+ use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , OwnerId , PatKind , find_attr} ;
3232use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
3333use rustc_middle:: query:: Providers ;
3434use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
@@ -599,7 +599,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
599599 DefKind :: Struct | DefKind :: Union => {
600600 // While structs and unions have type privacy, their fields do not.
601601 let struct_def = self . tcx . adt_def ( def_id) ;
602- for field in struct_def. non_enum_variant ( ) . fields . iter ( ) {
602+ for field in & struct_def. non_enum_variant ( ) . fields {
603603 let def_id = field. did . expect_local ( ) ;
604604 let field_vis = self . tcx . local_visibility ( def_id) ;
605605 if field_vis. is_accessible_from ( module, self . tcx ) {
@@ -637,58 +637,62 @@ impl<'tcx> EmbargoVisitor<'tcx> {
637637 }
638638}
639639
640- impl < ' tcx > Visitor < ' tcx > for EmbargoVisitor < ' tcx > {
641- fn visit_item ( & mut self , item : & ' tcx hir :: Item < ' tcx > ) {
640+ impl < ' tcx > EmbargoVisitor < ' tcx > {
641+ fn check_def_id ( & mut self , owner_id : OwnerId ) {
642642 // Update levels of nested things and mark all items
643643 // in interfaces of reachable items as reachable.
644- let item_ev = self . get ( item . owner_id . def_id ) ;
645- match item . kind {
644+ let item_ev = self . get ( owner_id. def_id ) ;
645+ match self . tcx . def_kind ( owner_id ) {
646646 // The interface is empty, and no nested items.
647- hir:: ItemKind :: Use ( ..)
648- | hir:: ItemKind :: ExternCrate ( ..)
649- | hir:: ItemKind :: GlobalAsm { .. } => { }
650- // The interface is empty, and all nested items are processed by `visit_item`.
651- hir:: ItemKind :: Mod ( ..) => { }
652- hir:: ItemKind :: Macro ( _, macro_def, _) => {
647+ DefKind :: Use | DefKind :: ExternCrate | DefKind :: GlobalAsm => { }
648+ // The interface is empty, and all nested items are processed by `check_def_id`.
649+ DefKind :: Mod => { }
650+ DefKind :: Macro { .. } => {
653651 if let Some ( item_ev) = item_ev {
654- self . update_reachability_from_macro ( item. owner_id . def_id , macro_def, item_ev) ;
652+ let ( _, macro_def, _) =
653+ self . tcx . hir_expect_item ( owner_id. def_id ) . expect_macro ( ) ;
654+ self . update_reachability_from_macro ( owner_id. def_id , macro_def, item_ev) ;
655655 }
656656 }
657- hir:: ItemKind :: Const ( ..)
658- | hir:: ItemKind :: Static ( ..)
659- | hir:: ItemKind :: Fn { .. }
660- | hir:: ItemKind :: TyAlias ( ..) => {
657+ DefKind :: ForeignTy
658+ | DefKind :: Const
659+ | DefKind :: Static { .. }
660+ | DefKind :: Fn
661+ | DefKind :: TyAlias => {
661662 if let Some ( item_ev) = item_ev {
662- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
663+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
663664 }
664665 }
665- hir :: ItemKind :: Trait ( .. , trait_item_refs ) => {
666+ DefKind :: Trait => {
666667 if let Some ( item_ev) = item_ev {
667- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
668+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
669+
670+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
671+ if assoc_item. is_impl_trait_in_trait ( ) {
672+ continue ;
673+ }
668674
669- for trait_item_ref in trait_item_refs {
670- self . update ( trait_item_ref . owner_id . def_id , item_ev, Level :: Reachable ) ;
675+ let def_id = assoc_item . def_id . expect_local ( ) ;
676+ self . update ( def_id, item_ev, Level :: Reachable ) ;
671677
672678 let tcx = self . tcx ;
673- let mut reach = self . reach ( trait_item_ref . owner_id . def_id , item_ev) ;
679+ let mut reach = self . reach ( def_id, item_ev) ;
674680 reach. generics ( ) . predicates ( ) ;
675681
676- if let DefKind :: AssocTy = tcx. def_kind ( trait_item_ref. owner_id )
677- && !tcx. defaultness ( trait_item_ref. owner_id ) . has_value ( )
678- {
682+ if assoc_item. is_type ( ) && !assoc_item. defaultness ( tcx) . has_value ( ) {
679683 // No type to visit.
680684 } else {
681685 reach. ty ( ) ;
682686 }
683687 }
684688 }
685689 }
686- hir :: ItemKind :: TraitAlias ( .. ) => {
690+ DefKind :: TraitAlias => {
687691 if let Some ( item_ev) = item_ev {
688- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
692+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
689693 }
690694 }
691- hir :: ItemKind :: Impl ( impl_ ) => {
695+ DefKind :: Impl { of_trait } => {
692696 // Type inference is very smart sometimes. It can make an impl reachable even some
693697 // components of its type or trait are unreachable. E.g. methods of
694698 // `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -700,85 +704,100 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
700704 // without knowing both "shallow" version of its self type and "shallow" version of
701705 // its trait if it exists (which require reaching the `DefId`s in them).
702706 let item_ev = EffectiveVisibility :: of_impl :: < true > (
703- item . owner_id . def_id ,
707+ owner_id. def_id ,
704708 self . tcx ,
705709 & self . effective_visibilities ,
706710 ) ;
707711
708- self . update_eff_vis ( item. owner_id . def_id , item_ev, None , Level :: Direct ) ;
712+ self . update_eff_vis ( owner_id. def_id , item_ev, None , Level :: Direct ) ;
713+
714+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
709715
710- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
716+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
717+ if assoc_item. is_impl_trait_in_trait ( ) {
718+ continue ;
719+ }
711720
712- for impl_item_ref in impl_. items {
713- let def_id = impl_item_ref. owner_id . def_id ;
721+ let def_id = assoc_item. def_id . expect_local ( ) ;
714722 let max_vis =
715- impl_ . of_trait . is_none ( ) . then ( || self . tcx . local_visibility ( def_id) ) ;
723+ if of_trait { None } else { Some ( self . tcx . local_visibility ( def_id) ) } ;
716724 self . update_eff_vis ( def_id, item_ev, max_vis, Level :: Direct ) ;
717725
718726 if let Some ( impl_item_ev) = self . get ( def_id) {
719727 self . reach ( def_id, impl_item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
720728 }
721729 }
722730 }
723- hir :: ItemKind :: Enum ( _ , _ , ref def ) => {
731+ DefKind :: Enum => {
724732 if let Some ( item_ev) = item_ev {
725- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
733+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
726734 }
727- for variant in def. variants {
735+ let def = self . tcx . adt_def ( owner_id) ;
736+ for variant in def. variants ( ) {
728737 if let Some ( item_ev) = item_ev {
729- self . update ( variant. def_id , item_ev, Level :: Reachable ) ;
738+ self . update ( variant. def_id . expect_local ( ) , item_ev, Level :: Reachable ) ;
730739 }
731740
732- if let Some ( variant_ev) = self . get ( variant. def_id ) {
733- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
734- self . update ( ctor_def_id, variant_ev, Level :: Reachable ) ;
741+ if let Some ( variant_ev) = self . get ( variant. def_id . expect_local ( ) ) {
742+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
743+ self . update ( ctor_def_id. expect_local ( ) , variant_ev, Level :: Reachable ) ;
735744 }
736745
737- for field in variant. data . fields ( ) {
738- self . update ( field. def_id , variant_ev, Level :: Reachable ) ;
739- self . reach ( field. def_id , variant_ev) . ty ( ) ;
746+ for field in & variant. fields {
747+ let field = field. did . expect_local ( ) ;
748+ self . update ( field, variant_ev, Level :: Reachable ) ;
749+ self . reach ( field, variant_ev) . ty ( ) ;
740750 }
741751 // Corner case: if the variant is reachable, but its
742752 // enum is not, make the enum reachable as well.
743- self . reach ( item . owner_id . def_id , variant_ev) . ty ( ) ;
753+ self . reach ( owner_id. def_id , variant_ev) . ty ( ) ;
744754 }
745- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
746- if let Some ( ctor_ev) = self . get ( ctor_def_id) {
747- self . reach ( item . owner_id . def_id , ctor_ev) . ty ( ) ;
755+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
756+ if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
757+ self . reach ( owner_id. def_id , ctor_ev) . ty ( ) ;
748758 }
749759 }
750760 }
751761 }
752- hir:: ItemKind :: ForeignMod { items, .. } => {
753- for foreign_item in items {
754- if let Some ( foreign_item_ev) = self . get ( foreign_item. owner_id . def_id ) {
755- self . reach ( foreign_item. owner_id . def_id , foreign_item_ev)
756- . generics ( )
757- . predicates ( )
758- . ty ( ) ;
759- }
760- }
761- }
762- hir:: ItemKind :: Struct ( _, _, ref struct_def)
763- | hir:: ItemKind :: Union ( _, _, ref struct_def) => {
762+ DefKind :: Struct | DefKind :: Union => {
763+ let def = self . tcx . adt_def ( owner_id) . non_enum_variant ( ) ;
764764 if let Some ( item_ev) = item_ev {
765- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
766- for field in struct_def. fields ( ) {
767- self . update ( field. def_id , item_ev, Level :: Reachable ) ;
768- if let Some ( field_ev) = self . get ( field. def_id ) {
769- self . reach ( field. def_id , field_ev) . ty ( ) ;
765+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
766+ for field in & def. fields {
767+ let field = field. did . expect_local ( ) ;
768+ self . update ( field, item_ev, Level :: Reachable ) ;
769+ if let Some ( field_ev) = self . get ( field) {
770+ self . reach ( field, field_ev) . ty ( ) ;
770771 }
771772 }
772773 }
773- if let Some ( ctor_def_id) = struct_def . ctor_def_id ( ) {
774+ if let Some ( ctor_def_id) = def . ctor_def_id ( ) {
774775 if let Some ( item_ev) = item_ev {
775- self . update ( ctor_def_id, item_ev, Level :: Reachable ) ;
776+ self . update ( ctor_def_id. expect_local ( ) , item_ev, Level :: Reachable ) ;
776777 }
777- if let Some ( ctor_ev) = self . get ( ctor_def_id) {
778- self . reach ( item . owner_id . def_id , ctor_ev) . ty ( ) ;
778+ if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
779+ self . reach ( owner_id. def_id , ctor_ev) . ty ( ) ;
779780 }
780781 }
781782 }
783+ // Contents are checked directly.
784+ DefKind :: ForeignMod => { }
785+ DefKind :: Field
786+ | DefKind :: Variant
787+ | DefKind :: AssocFn
788+ | DefKind :: AssocTy
789+ | DefKind :: AssocConst
790+ | DefKind :: TyParam
791+ | DefKind :: AnonConst
792+ | DefKind :: InlineConst
793+ | DefKind :: OpaqueTy
794+ | DefKind :: Closure
795+ | DefKind :: SyntheticCoroutineBody
796+ | DefKind :: ConstParam
797+ | DefKind :: LifetimeParam
798+ | DefKind :: Ctor ( ..) => {
799+ bug ! ( "should be checked while checking parent" )
800+ }
782801 }
783802 }
784803}
@@ -839,7 +858,7 @@ pub struct TestReachabilityVisitor<'a, 'tcx> {
839858}
840859
841860impl < ' a , ' tcx > TestReachabilityVisitor < ' a , ' tcx > {
842- fn effective_visibility_diagnostic ( & mut self , def_id : LocalDefId ) {
861+ fn effective_visibility_diagnostic ( & self , def_id : LocalDefId ) {
843862 if self . tcx . has_attr ( def_id, sym:: rustc_effective_visibility) {
844863 let mut error_msg = String :: new ( ) ;
845864 let span = self . tcx . def_span ( def_id. to_def_id ( ) ) ;
@@ -859,43 +878,35 @@ impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
859878 }
860879}
861880
862- impl < ' a , ' tcx > Visitor < ' tcx > for TestReachabilityVisitor < ' a , ' tcx > {
863- fn visit_item ( & mut self , item : & ' tcx hir :: Item < ' tcx > ) {
864- self . effective_visibility_diagnostic ( item . owner_id . def_id ) ;
881+ impl < ' a , ' tcx > TestReachabilityVisitor < ' a , ' tcx > {
882+ fn check_def_id ( & self , owner_id : OwnerId ) {
883+ self . effective_visibility_diagnostic ( owner_id. def_id ) ;
865884
866- match item. kind {
867- hir:: ItemKind :: Enum ( _, _, ref def) => {
868- for variant in def. variants . iter ( ) {
869- self . effective_visibility_diagnostic ( variant. def_id ) ;
870- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
871- self . effective_visibility_diagnostic ( ctor_def_id) ;
885+ match self . tcx . def_kind ( owner_id) {
886+ DefKind :: Enum => {
887+ let def = self . tcx . adt_def ( owner_id. def_id ) ;
888+ for variant in def. variants ( ) {
889+ self . effective_visibility_diagnostic ( variant. def_id . expect_local ( ) ) ;
890+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
891+ self . effective_visibility_diagnostic ( ctor_def_id. expect_local ( ) ) ;
872892 }
873- for field in variant. data . fields ( ) {
874- self . effective_visibility_diagnostic ( field. def_id ) ;
893+ for field in & variant. fields {
894+ self . effective_visibility_diagnostic ( field. did . expect_local ( ) ) ;
875895 }
876896 }
877897 }
878- hir:: ItemKind :: Struct ( _, _, ref def) | hir:: ItemKind :: Union ( _, _, ref def) => {
898+ DefKind :: Struct | DefKind :: Union => {
899+ let def = self . tcx . adt_def ( owner_id. def_id ) . non_enum_variant ( ) ;
879900 if let Some ( ctor_def_id) = def. ctor_def_id ( ) {
880- self . effective_visibility_diagnostic ( ctor_def_id) ;
901+ self . effective_visibility_diagnostic ( ctor_def_id. expect_local ( ) ) ;
881902 }
882- for field in def. fields ( ) {
883- self . effective_visibility_diagnostic ( field. def_id ) ;
903+ for field in & def. fields {
904+ self . effective_visibility_diagnostic ( field. did . expect_local ( ) ) ;
884905 }
885906 }
886907 _ => { }
887908 }
888909 }
889-
890- fn visit_trait_item ( & mut self , item : & ' tcx hir:: TraitItem < ' tcx > ) {
891- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
892- }
893- fn visit_impl_item ( & mut self , item : & ' tcx hir:: ImplItem < ' tcx > ) {
894- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
895- }
896- fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem < ' tcx > ) {
897- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
898- }
899910}
900911
901912//////////////////////////////////////////////////////////////////////////////////////
@@ -1836,8 +1847,14 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
18361847 visitor. changed = false ;
18371848 }
18381849
1850+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
18391851 loop {
1840- tcx. hir_visit_all_item_likes_in_crate ( & mut visitor) ;
1852+ for id in crate_items. free_items ( ) {
1853+ visitor. check_def_id ( id. owner_id ) ;
1854+ }
1855+ for id in crate_items. foreign_items ( ) {
1856+ visitor. check_def_id ( id. owner_id ) ;
1857+ }
18411858 if visitor. changed {
18421859 visitor. changed = false ;
18431860 } else {
@@ -1846,10 +1863,11 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
18461863 }
18471864 visitor. effective_visibilities . check_invariants ( tcx) ;
18481865
1849- let mut check_visitor =
1866+ let check_visitor =
18501867 TestReachabilityVisitor { tcx, effective_visibilities : & visitor. effective_visibilities } ;
1851- check_visitor. effective_visibility_diagnostic ( CRATE_DEF_ID ) ;
1852- tcx. hir_visit_all_item_likes_in_crate ( & mut check_visitor) ;
1868+ for id in crate_items. owners ( ) {
1869+ check_visitor. check_def_id ( id) ;
1870+ }
18531871
18541872 tcx. arena . alloc ( visitor. effective_visibilities )
18551873}
0 commit comments