Skip to content

Commit b5712d4

Browse files
committed
rustdoc: calculate effective visibilities of crates on-demand
1 parent 5c7ae0c commit b5712d4

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

src/librustdoc/core.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,7 @@ pub(crate) fn run_global_ctxt(
383383
show_coverage,
384384
};
385385

386-
for cnum in tcx.crates(()) {
387-
crate::visit_lib::lib_embargo_visit_item(&mut ctxt, cnum.as_def_id());
388-
}
386+
ctxt.cache.effective_visibilities.document_hidden = ctxt.render_options.document_hidden;
389387

390388
// Small hack to force the Sized trait to be present.
391389
//

src/librustdoc/visit_lib.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
use std::sync::RwLock;
2+
3+
use rustc_data_structures::fx::FxHashSet;
14
use rustc_hir::def::DefKind;
2-
use rustc_hir::def_id::{DefId, DefIdSet};
5+
use rustc_hir::def_id::{CrateNum, DefId, DefIdSet};
36
use rustc_middle::ty::TyCtxt;
47

58
use crate::core::DocContext;
@@ -8,6 +11,13 @@ use crate::core::DocContext;
811

912
#[derive(Default)]
1013
pub(crate) struct RustdocEffectiveVisibilities {
14+
inner: RwLock<VisInner>,
15+
pub(crate) document_hidden: bool,
16+
}
17+
18+
#[derive(Default)]
19+
struct VisInner {
20+
visited: FxHashSet<CrateNum>,
1121
extern_public: DefIdSet,
1222
}
1323

@@ -16,7 +26,18 @@ macro_rules! define_method {
1626
pub(crate) fn $method(&self, tcx: TyCtxt<'_>, def_id: DefId) -> bool {
1727
match def_id.as_local() {
1828
Some(def_id) => tcx.effective_visibilities(()).$method(def_id),
19-
None => self.extern_public.contains(&def_id),
29+
None => {
30+
let vis = self.inner.read().unwrap();
31+
if vis.visited.contains(&def_id.krate) {
32+
vis.extern_public.contains(&def_id)
33+
} else {
34+
std::mem::drop(vis);
35+
lib_embargo_visit_item_(&self, tcx, def_id.krate.as_def_id());
36+
let mut vis = self.inner.write().unwrap();
37+
vis.visited.insert(def_id.krate);
38+
vis.extern_public.contains(&def_id)
39+
}
40+
}
2041
}
2142
}
2243
};
@@ -28,17 +49,26 @@ impl RustdocEffectiveVisibilities {
2849
define_method!(is_reachable);
2950
}
3051

31-
pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
52+
pub(crate) fn lib_embargo_visit_item_(
53+
vis: &RustdocEffectiveVisibilities,
54+
tcx: TyCtxt<'_>,
55+
def_id: DefId,
56+
) {
3257
assert!(!def_id.is_local());
3358
LibEmbargoVisitor {
34-
tcx: cx.tcx,
35-
extern_public: &mut cx.cache.effective_visibilities.extern_public,
59+
tcx,
60+
extern_public: &mut vis.inner.write().unwrap().extern_public,
3661
visited_mods: Default::default(),
37-
document_hidden: cx.render_options.document_hidden,
62+
document_hidden: vis.document_hidden,
3863
}
3964
.visit_item(def_id)
4065
}
4166

67+
pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
68+
assert_eq!(cx.cache.effective_visibilities.document_hidden, cx.render_options.document_hidden);
69+
lib_embargo_visit_item_(&cx.cache.effective_visibilities, cx.tcx, def_id)
70+
}
71+
4272
/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
4373
/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
4474
struct LibEmbargoVisitor<'a, 'tcx> {

0 commit comments

Comments
 (0)