Skip to content

Commit cf797a3

Browse files
committed
Auto merge of #156228 - Bryanskiy:eff_vis_iter_late, r=<try>
Privacy: try use queue instead of fixed-point iteration
2 parents e95e732 + 70befe0 commit cf797a3

1 file changed

Lines changed: 80 additions & 40 deletions

File tree

  • compiler/rustc_privacy/src

compiler/rustc_privacy/src/lib.rs

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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

442442
struct 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

Comments
 (0)