about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-10-13 16:53:48 +0400
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-10-29 23:17:17 +0400
commit3f21bdd9941bb72c0ac83f033fa59674e555a1d8 (patch)
treeeffb2f166e7ff5298457e9a7a57a824b1e4e9f25
parent68c836a904e5a421712db311421c5266f9ce71c0 (diff)
downloadrust-3f21bdd9941bb72c0ac83f033fa59674e555a1d8.tar.gz
rust-3f21bdd9941bb72c0ac83f033fa59674e555a1d8.zip
rustdoc: Simplify modifications of effective visibility table
-rw-r--r--src/librustdoc/clean/utils.rs3
-rw-r--r--src/librustdoc/visit_ast.rs23
-rw-r--r--src/librustdoc/visit_lib.rs85
3 files changed, 32 insertions, 79 deletions
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 4572a712258..8f3e29a31a0 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -8,7 +8,6 @@ use crate::clean::{
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
-use crate::visit_lib::LibEmbargoVisitor;
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenTree;
@@ -32,7 +31,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
 
     for &cnum in cx.tcx.crates(()) {
         // Analyze doc-reachability for extern items
-        LibEmbargoVisitor::new(cx).visit_lib(cnum);
+        crate::visit_lib::lib_embargo_visit_item(cx, cnum.as_def_id());
     }
 
     // Clean the crate, translating the entire librustc_ast AST to one that is
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 06dffce555f..7960ab251b7 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -7,15 +7,14 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
 use rustc_hir::CRATE_HIR_ID;
-use rustc_middle::middle::privacy::Level;
-use rustc_middle::ty::{TyCtxt, Visibility};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
 use std::mem;
 
-use crate::clean::{self, cfg::Cfg, AttributesExt, NestedAttributesExt};
+use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt};
 use crate::core;
 
 /// This module is used to store stuff from Rust's AST in a more convenient
@@ -221,23 +220,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         // made reachable by cross-crate inlining which we're checking here.
         // (this is done here because we need to know this upfront).
         if !res_did.is_local() && !is_no_inline {
-            let attrs = clean::inline::load_attrs(self.cx, res_did);
-            let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
-            if !self_is_hidden {
-                if let Res::Def(kind, did) = res {
-                    if kind == DefKind::Mod {
-                        crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did)
-                    } else {
-                        // All items need to be handled here in case someone wishes to link
-                        // to them with intra-doc links
-                        self.cx.cache.effective_visibilities.set_public_at_level(
-                            did,
-                            || Visibility::Restricted(CRATE_DEF_ID),
-                            Level::Direct,
-                        );
-                    }
-                }
-            }
+            crate::visit_lib::lib_embargo_visit_item(self.cx, res_did);
             return false;
         }
 
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 70214e2adba..04a3114556e 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,86 +1,57 @@
+use crate::core::DocContext;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
 use rustc_middle::ty::{TyCtxt, Visibility};
 
 // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
 
+pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
+    assert!(!def_id.is_local());
+    LibEmbargoVisitor {
+        tcx: cx.tcx,
+        effective_visibilities: &mut cx.cache.effective_visibilities,
+        visited_mods: FxHashSet::default(),
+    }
+    .visit_item(def_id)
+}
+
 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
 /// specific rustdoc annotations into account (i.e., `doc(hidden)`)
-pub(crate) struct LibEmbargoVisitor<'a, 'tcx> {
+struct LibEmbargoVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     // Effective visibilities for reachable nodes
     effective_visibilities: &'a mut EffectiveVisibilities<DefId>,
-    // Previous level, None means unreachable
-    prev_level: Option<Level>,
     // Keeps track of already visited modules, in case a module re-exports its parent
     visited_mods: FxHashSet<DefId>,
 }
 
-impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
-    pub(crate) fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
-        LibEmbargoVisitor {
-            tcx: cx.tcx,
-            effective_visibilities: &mut cx.cache.effective_visibilities,
-            prev_level: Some(Level::Direct),
-            visited_mods: FxHashSet::default(),
-        }
-    }
-
-    pub(crate) fn visit_lib(&mut self, cnum: CrateNum) {
-        let did = cnum.as_def_id();
-        self.update(did, Some(Level::Direct));
-        self.visit_mod(did);
-    }
-
-    // Updates node level and returns the updated level
-    fn update(&mut self, did: DefId, level: Option<Level>) -> Option<Level> {
-        let is_hidden = self.tcx.is_doc_hidden(did);
-
-        let old_level = self.effective_visibilities.public_at_level(did);
-        // Visibility levels can only grow
-        if level > old_level && !is_hidden {
-            self.effective_visibilities.set_public_at_level(
-                did,
-                || Visibility::Restricted(CRATE_DEF_ID),
-                level.unwrap(),
-            );
-            level
-        } else {
-            old_level
-        }
-    }
-
-    pub(crate) fn visit_mod(&mut self, def_id: DefId) {
+impl LibEmbargoVisitor<'_, '_> {
+    fn visit_mod(&mut self, def_id: DefId) {
         if !self.visited_mods.insert(def_id) {
             return;
         }
 
         for item in self.tcx.module_children(def_id).iter() {
             if let Some(def_id) = item.res.opt_def_id() {
-                if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index)
-                    || item.vis.is_public()
-                {
-                    self.visit_item(item.res);
+                if item.vis.is_public() {
+                    self.visit_item(def_id);
                 }
             }
         }
     }
 
-    fn visit_item(&mut self, res: Res<!>) {
-        let def_id = res.def_id();
-        let vis = self.tcx.visibility(def_id);
-        let inherited_item_level = if vis.is_public() { self.prev_level } else { None };
-
-        let item_level = self.update(def_id, inherited_item_level);
-
-        if let Res::Def(DefKind::Mod, _) = res {
-            let orig_level = self.prev_level;
-
-            self.prev_level = item_level;
-            self.visit_mod(def_id);
-            self.prev_level = orig_level;
+    fn visit_item(&mut self, def_id: DefId) {
+        if !self.tcx.is_doc_hidden(def_id) {
+            self.effective_visibilities.set_public_at_level(
+                def_id,
+                || Visibility::Restricted(CRATE_DEF_ID),
+                Level::Direct,
+            );
+            if self.tcx.def_kind(def_id) == DefKind::Mod {
+                self.visit_mod(def_id);
+            }
         }
     }
 }