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-19 01:52:49 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-11-24 00:03:51 +0300
commit3f20f4ac42be55f309224ef365dfa2ca64359e07 (patch)
tree92db5edce2086f35428f85d5218f38d87e8d7510 /compiler/rustc_resolve/src
parentd121aa3b5584eb919a4aaf64dbae0ea1e8e30231 (diff)
downloadrust-3f20f4ac42be55f309224ef365dfa2ca64359e07.tar.gz
rust-3f20f4ac42be55f309224ef365dfa2ca64359e07.zip
effective visibility: Satisfy borrow checker to use resolver lazily from a closure
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs39
1 files changed, 26 insertions, 13 deletions
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index 82dcc7efb1b..57fb1fa9389 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -7,7 +7,8 @@ use rustc_ast::EnumDef;
 use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def_id::CRATE_DEF_ID;
-use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
+use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility};
+use rustc_middle::middle::privacy::{IntoDefIdTree, Level};
 use rustc_middle::ty::Visibility;
 
 type ImportId<'a> = Interned<'a, NameBinding<'a>>;
@@ -29,6 +30,7 @@ impl ParentId<'_> {
 
 pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
     r: &'r mut Resolver<'a>,
+    def_effective_visibilities: EffectiveVisibilities,
     /// While walking import chains we need to track effective visibilities per-binding, and def id
     /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
     /// bindings can correspond to a single def id in imports. So we keep a separate table.
@@ -36,6 +38,19 @@ pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
     changed: bool,
 }
 
+impl Resolver<'_> {
+    fn nearest_normal_mod(&mut self, def_id: LocalDefId) -> LocalDefId {
+        self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local()
+    }
+}
+
+impl<'a, 'b> IntoDefIdTree for &'b mut Resolver<'a> {
+    type Tree = &'b Resolver<'a>;
+    fn tree(self) -> Self::Tree {
+        self
+    }
+}
+
 impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
     /// Fills the `Resolver::effective_visibilities` table with public & exported items
     /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
@@ -43,6 +58,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
     pub fn compute_effective_visibilities<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
         let mut visitor = EffectiveVisibilitiesVisitor {
             r,
+            def_effective_visibilities: Default::default(),
             import_effective_visibilities: Default::default(),
             changed: false,
         };
@@ -54,6 +70,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
             visitor.changed = false;
             visit::walk_crate(&mut visitor, krate);
         }
+        visitor.r.effective_visibilities = visitor.def_effective_visibilities;
 
         // Update visibilities for import def ids. These are not used during the
         // `EffectiveVisibilitiesVisitor` pass, because we have more detailed binding-based
@@ -90,10 +107,6 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
         info!("resolve::effective_visibilities: {:#?}", r.effective_visibilities);
     }
 
-    fn nearest_normal_mod(&mut self, def_id: LocalDefId) -> LocalDefId {
-        self.r.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local()
-    }
-
     /// Update effective visibilities of bindings in the given module,
     /// including their whole reexport chains.
     fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
@@ -124,7 +137,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
 
     fn effective_vis(&self, parent_id: ParentId<'a>) -> Option<EffectiveVisibility> {
         match parent_id {
-            ParentId::Def(def_id) => self.r.effective_visibilities.effective_vis(def_id),
+            ParentId::Def(def_id) => self.def_effective_visibilities.effective_vis(def_id),
             ParentId::Import(binding) => self.import_effective_visibilities.effective_vis(binding),
         }
         .copied()
@@ -150,7 +163,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
         let default_vis = Visibility::Restricted(
             import
                 .id()
-                .map(|id| self.nearest_normal_mod(self.r.local_def_id(id)))
+                .map(|id| self.r.nearest_normal_mod(self.r.local_def_id(id)))
                 .unwrap_or(CRATE_DEF_ID),
         );
         if self.is_noop_update(parent_id, nominal_vis, default_vis) {
@@ -159,25 +172,25 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
         self.changed |= self.import_effective_visibilities.update(
             binding,
             nominal_vis,
-            default_vis,
+            |r| (default_vis, r),
             self.effective_vis(parent_id),
             parent_id.level(),
-            ResolverTree(&self.r.definitions, &self.r.crate_loader),
+            &mut *self.r,
         );
     }
 
     fn update_def(&mut self, def_id: LocalDefId, nominal_vis: Visibility, parent_id: ParentId<'a>) {
-        let default_vis = Visibility::Restricted(self.nearest_normal_mod(def_id));
+        let default_vis = Visibility::Restricted(self.r.nearest_normal_mod(def_id));
         if self.is_noop_update(parent_id, nominal_vis, default_vis) {
             return;
         }
-        self.changed |= self.r.effective_visibilities.update(
+        self.changed |= self.def_effective_visibilities.update(
             def_id,
             nominal_vis,
-            if def_id == CRATE_DEF_ID { Visibility::Public } else { default_vis },
+            |r| (if def_id == CRATE_DEF_ID { Visibility::Public } else { default_vis }, r),
             self.effective_vis(parent_id),
             parent_id.level(),
-            ResolverTree(&self.r.definitions, &self.r.crate_loader),
+            &mut *self.r,
         );
     }