Skip to content

Commit 8050c19

Browse files
committed
Rustdoc-Json: Retain Stripped Modules when they are imported, not when they have items.
Fixes #101103 Fixes #100973
1 parent eaadb89 commit 8050c19

11 files changed

+107
-13
lines changed

src/librustdoc/json/conversions.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,14 @@ impl JsonRenderer<'_> {
4646
clean::KeywordItem => return None,
4747
clean::StrippedItem(ref inner) => {
4848
match &**inner {
49-
// We document non-empty stripped modules as with `Module::is_stripped` set to
49+
// We document stripped modules as with `Module::is_stripped` set to
5050
// `true`, to prevent contained items from being orphaned for downstream users,
5151
// as JSON does no inlining.
52-
clean::ModuleItem(m) if !m.items.is_empty() => from_clean_item(item, self.tcx),
52+
clean::ModuleItem(_)
53+
if self.imported_items.contains(&item_id.expect_def_id()) =>
54+
{
55+
from_clean_item(item, self.tcx)
56+
}
5357
_ => return None,
5458
}
5559
}

src/librustdoc/json/import_finder.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use rustc_data_structures::fx::FxHashSet;
2+
use rustc_hir::def_id::DefId;
3+
4+
use crate::{
5+
clean::{self, Import, ImportSource, Item},
6+
fold::DocFolder,
7+
};
8+
9+
/// Get the id's of all items that are `pub use`d in the crate.
10+
///
11+
/// We need this to know if a stripped module is `pub use mod::*`, to decide
12+
/// if it needs to be kept in the index, despite being stripped.
13+
///
14+
/// See [#100973](https://github.com/rust-lang/rust/issues/100973) and
15+
/// [#101103](https://github.com/rust-lang/rust/issues/101103) for times when
16+
/// this information is needed.
17+
pub(crate) fn get_imports(krate: clean::Crate) -> (clean::Crate, FxHashSet<DefId>) {
18+
let mut finder = ImportFinder { imported: FxHashSet::default() };
19+
let krate = finder.fold_crate(krate);
20+
(krate, finder.imported)
21+
}
22+
23+
struct ImportFinder {
24+
imported: FxHashSet<DefId>,
25+
}
26+
27+
impl DocFolder for ImportFinder {
28+
fn fold_item(&mut self, i: Item) -> Option<Item> {
29+
match *i.kind {
30+
clean::ImportItem(Import { source: ImportSource { did: Some(did), .. }, .. }) => {
31+
self.imported.insert(did);
32+
Some(i)
33+
}
34+
35+
_ => Some(self.fold_item_recur(i)),
36+
}
37+
}
38+
}

src/librustdoc/json/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
//! docs for usage and details.
66
77
mod conversions;
8+
mod import_finder;
89

910
use std::cell::RefCell;
1011
use std::fs::{create_dir_all, File};
1112
use std::io::{BufWriter, Write};
1213
use std::path::PathBuf;
1314
use std::rc::Rc;
1415

15-
use rustc_data_structures::fx::FxHashMap;
16+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1617
use rustc_hir::def_id::DefId;
1718
use rustc_middle::ty::TyCtxt;
1819
use rustc_session::Session;
@@ -39,6 +40,7 @@ pub(crate) struct JsonRenderer<'tcx> {
3940
/// The directory where the blob will be written to.
4041
out_path: PathBuf,
4142
cache: Rc<Cache>,
43+
imported_items: FxHashSet<DefId>,
4244
}
4345

4446
impl<'tcx> JsonRenderer<'tcx> {
@@ -157,12 +159,16 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
157159
tcx: TyCtxt<'tcx>,
158160
) -> Result<(Self, clean::Crate), Error> {
159161
debug!("Initializing json renderer");
162+
163+
let (krate, imported_items) = import_finder::get_imports(krate);
164+
160165
Ok((
161166
JsonRenderer {
162167
tcx,
163168
index: Rc::new(RefCell::new(FxHashMap::default())),
164169
out_path: options.output,
165170
cache: Rc::new(cache),
171+
imported_items,
166172
},
167173
krate,
168174
))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/100973
2+
3+
#![feature(no_core)]
4+
#![no_core]
5+
6+
// @set m1 = "$.index[*][?(@.name == 'm1' && @.kind == 'module')].id"
7+
// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.items" []
8+
// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.is_stripped" true
9+
mod m1 {
10+
pub fn f() {}
11+
}
12+
// @set m2 = "$.index[*][?(@.name == 'm2' && @.kind == 'module')].id"
13+
// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.items" []
14+
// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.is_stripped" true
15+
mod m2 {
16+
pub fn f(_: u8) {}
17+
}
18+
19+
// @set m1_use = "$.index[*][?(@.inner.name=='m1')].id"
20+
// @is "$.index[*][?(@.inner.name=='m1')].inner.id" $m1
21+
// @is "$.index[*][?(@.inner.name=='m1')].inner.glob" true
22+
pub use m1::*;
23+
// @set m2_use = "$.index[*][?(@.inner.name=='m2')].id"
24+
// @is "$.index[*][?(@.inner.name=='m2')].inner.id" $m2
25+
// @is "$.index[*][?(@.inner.name=='m2')].inner.glob" true
26+
pub use m2::*;
27+
28+
// @ismany "$.index[*][?(@.inner.is_crate==true)].inner.items[*]" $m1_use $m2_use
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/100973
2+
3+
// @is "$.index[*][?(@.name=='m1' && @.kind == 'module')].inner.is_stripped" true
4+
// @set m1 = "$.index[*][?(@.name=='m1')].id"
5+
mod m1 {}
6+
7+
// @is "$.index[*][?(@.inner.name=='m1' && @.kind=='import')].inner.id" $m1
8+
pub use m1::*;

src/test/rustdoc-json/reexport/in_root_and_mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#![feature(no_core)]
22
#![no_core]
33

4-
// @is "$.index[*][?(@.name=='foo')].kind" \"module\"
5-
// @is "$.index[*][?(@.name=='foo')].inner.is_stripped" "true"
4+
// @!has "$.index[*][?(@.name=='foo')]"
65
mod foo {
76
// @has "$.index[*][?(@.name=='Foo')]"
87
pub struct Foo;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/101103
2+
3+
#![feature(no_core)]
4+
#![no_core]
5+
6+
mod m1 {
7+
pub fn x() {}
8+
}
9+
10+
pub use m1::x;
11+
12+
// @has "$.index[*][?(@.name=='x' && @.kind=='function')]"
13+
// @has "$.index[*][?(@.kind=='import' && @.inner.name=='x')].inner.source" '"m1::x"'
14+
// @!has "$.index[*][?(@.name=='m1')]"

src/test/rustdoc-json/reexport/private_two_names.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
#![no_core]
77
#![feature(no_core)]
88

9-
// @is "$.index[*][?(@.name=='style')].kind" \"module\"
10-
// @is "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
9+
// @!has "$.index[*][?(@.name=='style')]"
1110
mod style {
1211
// @set color_struct_id = "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
1312
pub struct Color;

src/test/rustdoc-json/reexport/rename_private.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
#![no_core]
44
#![feature(no_core)]
55

6-
// @is "$.index[*][?(@.name=='inner')].kind" \"module\"
7-
// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
6+
// @!has "$.index[*][?(@.kind=='inner')]"
87
mod inner {
98
// @has "$.index[*][?(@.name=='Public')]"
109
pub struct Public;

src/test/rustdoc-json/reexport/simple_private.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
#![no_core]
33
#![feature(no_core)]
44

5-
// @is "$.index[*][?(@.name=='inner')].kind" \"module\"
6-
// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
5+
// @!has "$.index[*][?(@.name=='inner')]"
76
mod inner {
87
// @set pub_id = "$.index[*][?(@.name=='Public')].id"
98
pub struct Public;
109
}
1110

1211
// @is "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
12+
// @is "$.index[*][?(@.kind=='import')].inner.id" $pub_id
1313
// @set use_id = "$.index[*][?(@.kind=='import')].id"
1414
pub use inner::Public;
1515

16-
// @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
1716
// @ismany "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id

src/test/rustdoc-json/stripped_modules.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod pub_inner_unreachable {
1212
pub fn pub_inner_1() {}
1313
}
1414

15-
// @has "$.index[*][?(@.name=='pub_inner_reachable')]"
15+
// @!has "$.index[*][?(@.name=='pub_inner_reachable')]"
1616
mod pub_inner_reachable {
1717
// @has "$.index[*][?(@.name=='pub_inner_2')]"
1818
pub fn pub_inner_2() {}

0 commit comments

Comments
 (0)