Skip to content

Commit 3c55a26

Browse files
Correctly handle usage of private items in public API for JSON output format
1 parent 1a15c71 commit 3c55a26

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

src/librustdoc/core.rs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub(crate) struct DocContext<'tcx> {
8181
pub(crate) inlined: FxHashSet<ItemId>,
8282
/// Used by `calculate_doc_coverage`.
8383
pub(crate) output_format: OutputFormat,
84+
/// Used by `strip_private`.
85+
pub(crate) show_coverage: bool,
8486
}
8587

8688
impl<'tcx> DocContext<'tcx> {
@@ -381,6 +383,7 @@ pub(crate) fn run_global_ctxt(
381383
inlined: FxHashSet::default(),
382384
output_format,
383385
render_options,
386+
show_coverage,
384387
};
385388

386389
// Small hack to force the Sized trait to be present.

src/librustdoc/passes/strip_private.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
2424
retained: &mut retained,
2525
access_levels: &cx.cache.access_levels,
2626
update_retained: true,
27+
is_json_output: cx.output_format.is_json() && !cx.show_coverage,
2728
};
2829
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
2930
}

src/librustdoc/passes/stripper.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,29 @@ use rustc_hir::def_id::DefId;
33
use rustc_middle::middle::privacy::AccessLevels;
44
use std::mem;
55

6-
use crate::clean::{self, Item, ItemIdSet};
6+
use crate::clean::{self, Item, ItemId, ItemIdSet};
77
use crate::fold::{strip_item, DocFolder};
88
use crate::formats::cache::Cache;
99

1010
pub(crate) struct Stripper<'a> {
1111
pub(crate) retained: &'a mut ItemIdSet,
1212
pub(crate) access_levels: &'a AccessLevels<DefId>,
1313
pub(crate) update_retained: bool,
14+
pub(crate) is_json_output: bool,
15+
}
16+
17+
impl<'a> Stripper<'a> {
18+
// We need to handle this differently for the JSON output because some non exported items could
19+
// be used in public API. And so, we need these items as well. `is_exported` only checks if they
20+
// are in the public API, which is not enough.
21+
#[inline]
22+
fn is_item_reachable(&self, item_id: ItemId) -> bool {
23+
if self.is_json_output {
24+
self.access_levels.is_reachable(item_id.expect_def_id())
25+
} else {
26+
self.access_levels.is_exported(item_id.expect_def_id())
27+
}
28+
}
1429
}
1530

1631
impl<'a> DocFolder for Stripper<'a> {
@@ -45,9 +60,8 @@ impl<'a> DocFolder for Stripper<'a> {
4560
| clean::TraitAliasItem(..)
4661
| clean::MacroItem(..)
4762
| clean::ForeignTypeItem => {
48-
if i.item_id.is_local()
49-
&& !self.access_levels.is_exported(i.item_id.expect_def_id())
50-
{
63+
let item_id = i.item_id;
64+
if item_id.is_local() && !self.is_item_reachable(item_id) {
5165
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
5266
return None;
5367
}

0 commit comments

Comments
 (0)