about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-11-23 20:31:35 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-11-24 01:28:41 +0300
commit7e76d94a225ee53fde0ddbbfd7285890d006db43 (patch)
treeb02c6caeba997db44451d65d3b1915ed62de51ce /compiler/rustc_resolve/src
parenta45a302be536126accf29764b6a3dca39d57d0fe (diff)
downloadrust-7e76d94a225ee53fde0ddbbfd7285890d006db43.tar.gz
rust-7e76d94a225ee53fde0ddbbfd7285890d006db43.zip
effective visibility: Always add table entries for nodes used as parents
Previously if the parent was not in the table, and there was nothing to inherit from, the child's private visibility was used, but that's not correct - the parent may have a larger visibility so we should set it to at least the parent's private visibility.
That parent's private visibility is also inserted into the table for caching, so it's not recalculated later if used again.
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs21
1 files changed, 14 insertions, 7 deletions
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index 56959586d11..0f6db93c779 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -155,32 +155,39 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
         }
     }
 
-    fn effective_vis(&self, parent_id: ParentId<'a>) -> Option<EffectiveVisibility> {
-        match parent_id {
-            ParentId::Def(def_id) => self.def_effective_visibilities.effective_vis(def_id),
-            ParentId::Import(binding) => self.import_effective_visibilities.effective_vis(binding),
+    fn effective_vis_or_private(&mut self, parent_id: ParentId<'a>) -> EffectiveVisibility {
+        // Private nodes are only added to the table for caching, they could be added or removed at
+        // any moment without consequences, so we don't set `changed` to true when adding them.
+        *match parent_id {
+            ParentId::Def(def_id) => self
+                .def_effective_visibilities
+                .effective_vis_or_private(def_id, || self.r.private_vis_def(def_id)),
+            ParentId::Import(binding) => self
+                .import_effective_visibilities
+                .effective_vis_or_private(binding, || self.r.private_vis_import(binding)),
         }
-        .copied()
     }
 
     fn update_import(&mut self, binding: ImportId<'a>, parent_id: ParentId<'a>) {
         let nominal_vis = binding.vis.expect_local();
+        let inherited_eff_vis = self.effective_vis_or_private(parent_id);
         self.changed |= self.import_effective_visibilities.update(
             binding,
             nominal_vis,
             |r| (r.private_vis_import(binding), r),
-            self.effective_vis(parent_id),
+            inherited_eff_vis,
             parent_id.level(),
             &mut *self.r,
         );
     }
 
     fn update_def(&mut self, def_id: LocalDefId, nominal_vis: Visibility, parent_id: ParentId<'a>) {
+        let inherited_eff_vis = self.effective_vis_or_private(parent_id);
         self.changed |= self.def_effective_visibilities.update(
             def_id,
             nominal_vis,
             |r| (r.private_vis_def(def_id), r),
-            self.effective_vis(parent_id),
+            inherited_eff_vis,
             parent_id.level(),
             &mut *self.r,
         );