@@ -436,7 +436,7 @@ struct EmbargoVisitor<'tcx> {
436436 /// }
437437 macro_reachable : FxHashSet < ( LocalModDefId , LocalModDefId ) > ,
438438 /// Has something changed in the level map?
439- changed : bool ,
439+ queue : Vec < LocalDefId > ,
440440}
441441
442442struct ReachEverythingInTheInterfaceVisitor < ' a , ' tcx > {
@@ -472,15 +472,62 @@ impl<'tcx> EmbargoVisitor<'tcx> {
472472 // FIXME(typed_def_id): Make `Visibility::Restricted` use a `LocalModDefId` by default.
473473 let private_vis =
474474 ty:: Visibility :: Restricted ( self . tcx . parent_module_from_def_id ( def_id) . into ( ) ) ;
475- if max_vis != Some ( private_vis) {
476- self . changed |= self . effective_visibilities . update (
475+ if max_vis != Some ( private_vis)
476+ && self . effective_visibilities . update (
477477 def_id,
478478 max_vis,
479479 || private_vis,
480480 inherited_effective_vis,
481481 level,
482482 self . tcx ,
483- ) ;
483+ )
484+ {
485+ self . try_append_item_in_queue ( def_id)
486+ }
487+ }
488+
489+ fn try_append_item_in_queue ( & mut self , def_id : LocalDefId ) {
490+ match self . tcx . def_kind ( def_id) {
491+ DefKind :: Struct
492+ | DefKind :: Union
493+ | DefKind :: Enum
494+ | DefKind :: ForeignTy
495+ | DefKind :: Const { .. }
496+ | DefKind :: Static { .. }
497+ | DefKind :: Fn
498+ | DefKind :: TyAlias
499+ | DefKind :: Macro ( _)
500+ | DefKind :: Impl { .. } => {
501+ self . queue . push ( def_id) ;
502+ }
503+ DefKind :: TraitAlias | DefKind :: Trait => {
504+ self . queue . push ( def_id) ;
505+ let impls = self . tcx . all_impls ( def_id. to_def_id ( ) ) ;
506+ for impl_ in impls {
507+ if let Some ( impl_local) = impl_. as_local ( ) {
508+ self . queue . push ( impl_local) ;
509+ }
510+ }
511+ }
512+ DefKind :: ForeignMod
513+ | DefKind :: AssocTy
514+ | DefKind :: Field
515+ | DefKind :: Variant
516+ | DefKind :: AssocFn
517+ | DefKind :: AssocConst { .. }
518+ | DefKind :: TyParam
519+ | DefKind :: AnonConst
520+ | DefKind :: InlineConst
521+ | DefKind :: OpaqueTy
522+ | DefKind :: Closure
523+ | DefKind :: SyntheticCoroutineBody
524+ | DefKind :: ConstParam
525+ | DefKind :: LifetimeParam
526+ | DefKind :: Mod
527+ | DefKind :: Use
528+ | DefKind :: ExternCrate
529+ | DefKind :: GlobalAsm
530+ | DefKind :: Ctor ( ..) => { }
484531 }
485532 }
486533
@@ -680,20 +727,19 @@ impl<'tcx> EmbargoVisitor<'tcx> {
680727 }
681728 }
682729
683- fn check_def_id ( & mut self , owner_id : OwnerId ) {
730+ fn check_def_id ( & mut self , def_id : LocalDefId ) {
684731 // Update levels of nested things and mark all items
685732 // in interfaces of reachable items as reachable.
686- let item_ev = self . get ( owner_id . def_id ) ;
687- match self . tcx . def_kind ( owner_id ) {
733+ let item_ev = self . get ( def_id) ;
734+ match self . tcx . def_kind ( def_id ) {
688735 // The interface is empty, and no nested items.
689736 DefKind :: Use | DefKind :: ExternCrate | DefKind :: GlobalAsm => { }
690737 // The interface is empty, and all nested items are processed by `check_def_id`.
691738 DefKind :: Mod => { }
692739 DefKind :: Macro { .. } => {
693740 if let Some ( item_ev) = item_ev {
694- let ( _, macro_def, _) =
695- self . tcx . hir_expect_item ( owner_id. def_id ) . expect_macro ( ) ;
696- self . update_reachability_from_macro ( owner_id. def_id , macro_def, item_ev) ;
741+ let ( _, macro_def, _) = self . tcx . hir_expect_item ( def_id) . expect_macro ( ) ;
742+ self . update_reachability_from_macro ( def_id, macro_def, item_ev) ;
697743 }
698744 }
699745 DefKind :: ForeignTy
@@ -702,14 +748,14 @@ impl<'tcx> EmbargoVisitor<'tcx> {
702748 | DefKind :: Fn
703749 | DefKind :: TyAlias => {
704750 if let Some ( item_ev) = item_ev {
705- self . reach ( owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
751+ self . reach ( def_id, item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
706752 }
707753 }
708754 DefKind :: Trait => {
709755 if let Some ( item_ev) = item_ev {
710- self . reach ( owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
756+ self . reach ( def_id, item_ev) . generics ( ) . predicates ( ) ;
711757
712- for assoc_item in self . tcx . associated_items ( owner_id ) . in_definition_order ( ) {
758+ for assoc_item in self . tcx . associated_items ( def_id ) . in_definition_order ( ) {
713759 let def_id = assoc_item. def_id . expect_local ( ) ;
714760 self . update ( def_id, item_ev, Level :: Reachable ) ;
715761
@@ -719,7 +765,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
719765 }
720766 DefKind :: TraitAlias => {
721767 if let Some ( item_ev) = item_ev {
722- self . reach ( owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
768+ self . reach ( def_id, item_ev) . generics ( ) . predicates ( ) ;
723769 }
724770 }
725771 DefKind :: Impl { of_trait } => {
@@ -734,23 +780,23 @@ impl<'tcx> EmbargoVisitor<'tcx> {
734780 // without knowing both "shallow" version of its self type and "shallow" version of
735781 // its trait if it exists (which require reaching the `DefId`s in them).
736782 let item_ev = EffectiveVisibility :: of_impl :: < true > (
737- owner_id . def_id ,
783+ def_id,
738784 of_trait,
739785 self . tcx ,
740786 & self . effective_visibilities ,
741787 ) ;
742788
743- self . update_eff_vis ( owner_id . def_id , item_ev, None , Level :: Direct ) ;
789+ self . update_eff_vis ( def_id, item_ev, None , Level :: Direct ) ;
744790
745791 {
746- let mut reach = self . reach ( owner_id . def_id , item_ev) ;
792+ let mut reach = self . reach ( def_id, item_ev) ;
747793 reach. generics ( ) . predicates ( ) . ty ( ) ;
748794 if of_trait {
749795 reach. trait_ref ( ) ;
750796 }
751797 }
752798
753- for assoc_item in self . tcx . associated_items ( owner_id ) . in_definition_order ( ) {
799+ for assoc_item in self . tcx . associated_items ( def_id ) . in_definition_order ( ) {
754800 let def_id = assoc_item. def_id . expect_local ( ) ;
755801 let max_vis =
756802 if of_trait { None } else { Some ( self . tcx . local_visibility ( def_id) ) } ;
@@ -763,9 +809,9 @@ impl<'tcx> EmbargoVisitor<'tcx> {
763809 }
764810 DefKind :: Enum => {
765811 if let Some ( item_ev) = item_ev {
766- self . reach ( owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
812+ self . reach ( def_id, item_ev) . generics ( ) . predicates ( ) ;
767813 }
768- let def = self . tcx . adt_def ( owner_id ) ;
814+ let def = self . tcx . adt_def ( def_id ) ;
769815 for variant in def. variants ( ) {
770816 if let Some ( item_ev) = item_ev {
771817 self . update ( variant. def_id . expect_local ( ) , item_ev, Level :: Reachable ) ;
@@ -783,19 +829,19 @@ impl<'tcx> EmbargoVisitor<'tcx> {
783829 }
784830 // Corner case: if the variant is reachable, but its
785831 // enum is not, make the enum reachable as well.
786- self . reach ( owner_id . def_id , variant_ev) . ty ( ) ;
832+ self . reach ( def_id, variant_ev) . ty ( ) ;
787833 }
788834 if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
789835 if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
790- self . reach ( owner_id . def_id , ctor_ev) . ty ( ) ;
836+ self . reach ( def_id, ctor_ev) . ty ( ) ;
791837 }
792838 }
793839 }
794840 }
795841 DefKind :: Struct | DefKind :: Union => {
796- let def = self . tcx . adt_def ( owner_id ) . non_enum_variant ( ) ;
842+ let def = self . tcx . adt_def ( def_id ) . non_enum_variant ( ) ;
797843 if let Some ( item_ev) = item_ev {
798- self . reach ( owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
844+ self . reach ( def_id, item_ev) . generics ( ) . predicates ( ) ;
799845 for field in & def. fields {
800846 let field = field. did . expect_local ( ) ;
801847 self . update ( field, item_ev, Level :: Reachable ) ;
@@ -809,7 +855,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
809855 self . update ( ctor_def_id. expect_local ( ) , item_ev, Level :: Reachable ) ;
810856 }
811857 if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
812- self . reach ( owner_id . def_id , ctor_ev) . ty ( ) ;
858+ self . reach ( def_id, ctor_ev) . ty ( ) ;
813859 }
814860 }
815861 }
@@ -1816,7 +1862,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
18161862 tcx,
18171863 effective_visibilities : tcx. resolutions ( ( ) ) . effective_visibilities . clone ( ) ,
18181864 macro_reachable : Default :: default ( ) ,
1819- changed : false ,
1865+ queue : vec ! [ ] ,
18201866 } ;
18211867
18221868 visitor. effective_visibilities . check_invariants ( tcx) ;
@@ -1868,23 +1914,17 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
18681914 . ty ( ) ;
18691915 }
18701916 }
1871-
1872- visitor. changed = false ;
18731917 }
18741918
18751919 let crate_items = tcx. hir_crate_items ( ( ) ) ;
1876- loop {
1877- for id in crate_items. free_items ( ) {
1878- visitor. check_def_id ( id. owner_id ) ;
1879- }
1880- for id in crate_items. foreign_items ( ) {
1881- visitor. check_def_id ( id. owner_id ) ;
1882- }
1883- if visitor. changed {
1884- visitor. changed = false ;
1885- } else {
1886- break ;
1887- }
1920+ for id in crate_items. free_items ( ) {
1921+ visitor. check_def_id ( id. owner_id . def_id ) ;
1922+ }
1923+ for id in crate_items. foreign_items ( ) {
1924+ visitor. check_def_id ( id. owner_id . def_id ) ;
1925+ }
1926+ while let Some ( def_id) = visitor. queue . pop ( ) {
1927+ visitor. check_def_id ( def_id) ;
18881928 }
18891929 visitor. effective_visibilities . check_invariants ( tcx) ;
18901930
0 commit comments