@@ -474,7 +474,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
474474 fn update (
475475 & mut self ,
476476 def_id : LocalDefId ,
477- inherited_effective_vis : Option < EffectiveVisibility > ,
477+ inherited_effective_vis : EffectiveVisibility ,
478478 level : Level ,
479479 ) {
480480 let nominal_vis = self . tcx . local_visibility ( def_id) ;
@@ -484,23 +484,20 @@ impl<'tcx> EmbargoVisitor<'tcx> {
484484 fn update_eff_vis (
485485 & mut self ,
486486 def_id : LocalDefId ,
487- inherited_effective_vis : Option < EffectiveVisibility > ,
487+ inherited_effective_vis : EffectiveVisibility ,
488488 nominal_vis : Option < ty:: Visibility > ,
489489 level : Level ,
490490 ) {
491- if let Some ( inherited_effective_vis) = inherited_effective_vis {
492- let private_vis =
493- ty:: Visibility :: Restricted ( self . tcx . parent_module_from_def_id ( def_id) ) ;
494- if Some ( private_vis) != nominal_vis {
495- self . changed |= self . effective_visibilities . update (
496- def_id,
497- nominal_vis,
498- || private_vis,
499- inherited_effective_vis,
500- level,
501- self . tcx ,
502- ) ;
503- }
491+ let private_vis = ty:: Visibility :: Restricted ( self . tcx . parent_module_from_def_id ( def_id) ) ;
492+ if Some ( private_vis) != nominal_vis {
493+ self . changed |= self . effective_visibilities . update (
494+ def_id,
495+ nominal_vis,
496+ || private_vis,
497+ inherited_effective_vis,
498+ level,
499+ self . tcx ,
500+ ) ;
504501 }
505502 }
506503
@@ -532,9 +529,13 @@ impl<'tcx> EmbargoVisitor<'tcx> {
532529
533530 // We have to make sure that the items that macros might reference
534531 // are reachable, since they might be exported transitively.
535- fn update_reachability_from_macro ( & mut self , local_def_id : LocalDefId , md : & MacroDef ) {
532+ fn update_reachability_from_macro (
533+ & mut self ,
534+ local_def_id : LocalDefId ,
535+ md : & MacroDef ,
536+ macro_ev : EffectiveVisibility ,
537+ ) {
536538 // Non-opaque macros cannot make other items more accessible than they already are.
537-
538539 let hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( local_def_id) ;
539540 let attrs = self . tcx . hir ( ) . attrs ( hir_id) ;
540541 if attr:: find_transparency ( attrs, md. macro_rules ) . 0 != Transparency :: Opaque {
@@ -554,8 +555,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
554555 // Since we are starting from an externally visible module,
555556 // all the parents in the loop below are also guaranteed to be modules.
556557 let mut module_def_id = macro_module_def_id;
557- // If the macro eff vis is not in the table the condition above will return.
558- let macro_ev = self . get ( local_def_id) . unwrap ( ) ;
559558 loop {
560559 let changed_reachability =
561560 self . update_macro_reachable ( module_def_id, macro_module_def_id, macro_ev) ;
@@ -620,12 +619,12 @@ impl<'tcx> EmbargoVisitor<'tcx> {
620619 module : LocalDefId ,
621620 macro_ev : EffectiveVisibility ,
622621 ) {
623- self . update ( def_id, Some ( macro_ev) , Level :: Reachable ) ;
622+ self . update ( def_id, macro_ev, Level :: Reachable ) ;
624623 match def_kind {
625624 // No type privacy, so can be directly marked as reachable.
626625 DefKind :: Const | DefKind :: Static ( _) | DefKind :: TraitAlias | DefKind :: TyAlias => {
627626 if vis. is_accessible_from ( module, self . tcx ) {
628- self . update ( def_id, Some ( macro_ev) , Level :: Reachable ) ;
627+ self . update ( def_id, macro_ev, Level :: Reachable ) ;
629628 }
630629 }
631630
@@ -637,7 +636,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
637636 let item = self . tcx . hir ( ) . expect_item ( def_id) ;
638637 if let hir:: ItemKind :: Macro ( MacroDef { macro_rules : false , .. } , _) = item. kind {
639638 if vis. is_accessible_from ( module, self . tcx ) {
640- self . update ( def_id, Some ( macro_ev) , Level :: Reachable ) ;
639+ self . update ( def_id, macro_ev, Level :: Reachable ) ;
641640 }
642641 }
643642 }
@@ -701,86 +700,21 @@ impl<'tcx> EmbargoVisitor<'tcx> {
701700
702701impl < ' tcx > Visitor < ' tcx > for EmbargoVisitor < ' tcx > {
703702 fn visit_item ( & mut self , item : & ' tcx hir:: Item < ' tcx > ) {
704- let item_ev = match item. kind {
705- hir:: ItemKind :: Impl { .. } => {
706- let impl_ev = Option :: < EffectiveVisibility > :: of_impl (
707- item. owner_id . def_id ,
708- self . tcx ,
709- & self . effective_visibilities ,
710- ) ;
711-
712- self . update_eff_vis ( item. owner_id . def_id , impl_ev, None , Level :: Direct ) ;
713- impl_ev
714- }
715- _ => self . get ( item. owner_id . def_id ) ,
716- } ;
717-
718- // Update levels of nested things.
703+ // Update levels of nested things and mark all items
704+ // in interfaces of reachable items as reachable.
705+ let item_ev = self . get ( item. owner_id . def_id ) ;
719706 match item. kind {
720- hir:: ItemKind :: Enum ( ref def, _) => {
721- for variant in def. variants {
722- self . update ( variant. def_id , item_ev, Level :: Reachable ) ;
723- let variant_ev = self . get ( variant. def_id ) ;
724- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
725- self . update ( ctor_def_id, variant_ev, Level :: Reachable ) ;
726- }
727- for field in variant. data . fields ( ) {
728- self . update ( field. def_id , variant_ev, Level :: Reachable ) ;
729- }
730- }
731- }
732- hir:: ItemKind :: Impl ( ref impl_) => {
733- for impl_item_ref in impl_. items {
734- let def_id = impl_item_ref. id . owner_id . def_id ;
735- let nominal_vis =
736- impl_. of_trait . is_none ( ) . then ( || self . tcx . local_visibility ( def_id) ) ;
737- self . update_eff_vis ( def_id, item_ev, nominal_vis, Level :: Direct ) ;
738- }
739- }
740- hir:: ItemKind :: Trait ( .., trait_item_refs) => {
741- for trait_item_ref in trait_item_refs {
742- self . update ( trait_item_ref. id . owner_id . def_id , item_ev, Level :: Reachable ) ;
743- }
744- }
745- hir:: ItemKind :: Struct ( ref def, _) | hir:: ItemKind :: Union ( ref def, _) => {
746- if let Some ( ctor_def_id) = def. ctor_def_id ( ) {
747- self . update ( ctor_def_id, item_ev, Level :: Reachable ) ;
748- }
749- for field in def. fields ( ) {
750- self . update ( field. def_id , item_ev, Level :: Reachable ) ;
751- }
752- }
707+ // The interface is empty, and no nested items.
708+ hir:: ItemKind :: Use ( ..)
709+ | hir:: ItemKind :: ExternCrate ( ..)
710+ | hir:: ItemKind :: GlobalAsm ( ..) => { }
711+ // The interface is empty, and all nested items are processed by `visit_item`.
712+ hir:: ItemKind :: Mod ( ..) => { }
753713 hir:: ItemKind :: Macro ( ref macro_def, _) => {
754- self . update_reachability_from_macro ( item. owner_id . def_id , macro_def) ;
755- }
756- hir:: ItemKind :: ForeignMod { items, .. } => {
757- for foreign_item in items {
758- self . update ( foreign_item. id . owner_id . def_id , item_ev, Level :: Reachable ) ;
714+ if let Some ( item_ev) = item_ev {
715+ self . update_reachability_from_macro ( item. owner_id . def_id , macro_def, item_ev) ;
759716 }
760717 }
761-
762- hir:: ItemKind :: OpaqueTy ( ..)
763- | hir:: ItemKind :: Use ( ..)
764- | hir:: ItemKind :: Static ( ..)
765- | hir:: ItemKind :: Const ( ..)
766- | hir:: ItemKind :: GlobalAsm ( ..)
767- | hir:: ItemKind :: TyAlias ( ..)
768- | hir:: ItemKind :: Mod ( ..)
769- | hir:: ItemKind :: TraitAlias ( ..)
770- | hir:: ItemKind :: Fn ( ..)
771- | hir:: ItemKind :: ExternCrate ( ..) => { }
772- }
773-
774- // Mark all items in interfaces of reachable items as reachable.
775- match item. kind {
776- // The interface is empty.
777- hir:: ItemKind :: Macro ( ..) | hir:: ItemKind :: ExternCrate ( ..) => { }
778- // All nested items are checked by `visit_item`.
779- hir:: ItemKind :: Mod ( ..) => { }
780- // Handled in `rustc_resolve`.
781- hir:: ItemKind :: Use ( ..) => { }
782- // The interface is empty.
783- hir:: ItemKind :: GlobalAsm ( ..) => { }
784718 hir:: ItemKind :: OpaqueTy ( ref opaque) => {
785719 // HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
786720 // Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
@@ -797,7 +731,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
797731 . ty ( ) ;
798732 }
799733 }
800- // Visit everything.
801734 hir:: ItemKind :: Const ( ..)
802735 | hir:: ItemKind :: Static ( ..)
803736 | hir:: ItemKind :: Fn ( ..)
@@ -811,9 +744,10 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
811744 self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
812745
813746 for trait_item_ref in trait_item_refs {
747+ self . update ( trait_item_ref. id . owner_id . def_id , item_ev, Level :: Reachable ) ;
748+
814749 let tcx = self . tcx ;
815750 let mut reach = self . reach ( trait_item_ref. id . owner_id . def_id , item_ev) ;
816-
817751 reach. generics ( ) . predicates ( ) ;
818752
819753 if trait_item_ref. kind == AssocItemKind :: Type
@@ -831,34 +765,47 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
831765 self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
832766 }
833767 }
834- // Visit everything except for private impl items.
835768 hir:: ItemKind :: Impl ( ref impl_) => {
836- if let Some ( item_ev) = item_ev {
769+ if let Some ( item_ev) = Option :: < EffectiveVisibility > :: of_impl (
770+ item. owner_id . def_id ,
771+ self . tcx ,
772+ & self . effective_visibilities ,
773+ ) {
774+ self . update_eff_vis ( item. owner_id . def_id , item_ev, None , Level :: Direct ) ;
775+
837776 self . reach ( item. owner_id . def_id , item_ev)
838777 . generics ( )
839778 . predicates ( )
840779 . ty ( )
841780 . trait_ref ( ) ;
842781
843782 for impl_item_ref in impl_. items {
844- if let Some ( impl_item_ev) = self . get ( impl_item_ref. id . owner_id . def_id ) {
845- self . reach ( impl_item_ref. id . owner_id . def_id , impl_item_ev)
846- . generics ( )
847- . predicates ( )
848- . ty ( ) ;
783+ let def_id = impl_item_ref. id . owner_id . def_id ;
784+ let nominal_vis =
785+ impl_. of_trait . is_none ( ) . then ( || self . tcx . local_visibility ( def_id) ) ;
786+ self . update_eff_vis ( def_id, item_ev, nominal_vis, Level :: Direct ) ;
787+
788+ if let Some ( impl_item_ev) = self . get ( def_id) {
789+ self . reach ( def_id, impl_item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
849790 }
850791 }
851792 }
852793 }
853-
854- // Visit everything, but enum variants have their own levels.
855794 hir:: ItemKind :: Enum ( ref def, _) => {
856795 if let Some ( item_ev) = item_ev {
857796 self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
858797 }
859798 for variant in def. variants {
799+ if let Some ( item_ev) = item_ev {
800+ self . update ( variant. def_id , item_ev, Level :: Reachable ) ;
801+ }
802+
860803 if let Some ( variant_ev) = self . get ( variant. def_id ) {
804+ if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
805+ self . update ( ctor_def_id, variant_ev, Level :: Reachable ) ;
806+ }
861807 for field in variant. data . fields ( ) {
808+ self . update ( field. def_id , variant_ev, Level :: Reachable ) ;
862809 self . reach ( field. def_id , variant_ev) . ty ( ) ;
863810 }
864811 // Corner case: if the variant is reachable, but its
@@ -872,7 +819,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
872819 }
873820 }
874821 }
875- // Visit everything, but foreign items have their own levels.
876822 hir:: ItemKind :: ForeignMod { items, .. } => {
877823 for foreign_item in items {
878824 if let Some ( foreign_item_ev) = self . get ( foreign_item. id . owner_id . def_id ) {
@@ -883,17 +829,20 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
883829 }
884830 }
885831 }
886- // Visit everything except for private fields.
887832 hir:: ItemKind :: Struct ( ref struct_def, _) | hir:: ItemKind :: Union ( ref struct_def, _) => {
888833 if let Some ( item_ev) = item_ev {
889834 self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
890835 for field in struct_def. fields ( ) {
836+ self . update ( field. def_id , item_ev, Level :: Reachable ) ;
891837 if let Some ( field_ev) = self . get ( field. def_id ) {
892838 self . reach ( field. def_id , field_ev) . ty ( ) ;
893839 }
894840 }
895841 }
896842 if let Some ( ctor_def_id) = struct_def. ctor_def_id ( ) {
843+ if let Some ( item_ev) = item_ev {
844+ self . update ( ctor_def_id, item_ev, Level :: Reachable ) ;
845+ }
897846 if let Some ( ctor_ev) = self . get ( ctor_def_id) {
898847 self . reach ( item. owner_id . def_id , ctor_ev) . ty ( ) ;
899848 }
@@ -953,7 +902,7 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
953902 _descr : & dyn fmt:: Display ,
954903 ) -> ControlFlow < Self :: BreakTy > {
955904 if let Some ( def_id) = def_id. as_local ( ) {
956- self . ev . update_eff_vis ( def_id, Some ( self . effective_vis ) , None , self . level ) ;
905+ self . ev . update_eff_vis ( def_id, self . effective_vis , None , self . level ) ;
957906 }
958907 ControlFlow :: Continue ( ( ) )
959908 }
0 commit comments