Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/etc/check_missing_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,9 @@ def check_type(ty):
check_generic_bound(bound)
if item["inner"]["default"]:
check_type(item["inner"]["default"])
elif item["kind"] == "import":
if item["inner"]["id"]:
inner_id = item["inner"]["id"]
assert valid_id(inner_id)
if inner_id in crate["index"] and inner_id not in visited:
work_list.add(inner_id)
8 changes: 6 additions & 2 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,14 @@ impl JsonRenderer<'_> {
clean::KeywordItem => return None,
clean::StrippedItem(ref inner) => {
match &**inner {
// We document non-empty stripped modules as with `Module::is_stripped` set to
// We document stripped modules as with `Module::is_stripped` set to
// `true`, to prevent contained items from being orphaned for downstream users,
// as JSON does no inlining.
clean::ModuleItem(m) if !m.items.is_empty() => from_clean_item(item, self.tcx),
clean::ModuleItem(_)
if self.imported_items.contains(&item_id.expect_def_id()) =>
{
from_clean_item(item, self.tcx)
}
_ => return None,
}
}
Expand Down
38 changes: 38 additions & 0 deletions src/librustdoc/json/import_finder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;

use crate::{
clean::{self, Import, ImportSource, Item},
fold::DocFolder,
};

/// Get the id's of all items that are `pub use`d in the crate.
///
/// We need this to know if a stripped module is `pub use mod::*`, to decide
/// if it needs to be kept in the index, despite being stripped.
///
/// See [#100973](https://github.com/rust-lang/rust/issues/100973) and
/// [#101103](https://github.com/rust-lang/rust/issues/101103) for times when
/// this information is needed.
pub(crate) fn get_imports(krate: clean::Crate) -> (clean::Crate, FxHashSet<DefId>) {
let mut finder = ImportFinder { imported: FxHashSet::default() };
let krate = finder.fold_crate(krate);
(krate, finder.imported)
}

struct ImportFinder {
imported: FxHashSet<DefId>,
}

impl DocFolder for ImportFinder {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match *i.kind {
clean::ImportItem(Import { source: ImportSource { did: Some(did), .. }, .. }) => {
self.imported.insert(did);
Some(i)
}

_ => Some(self.fold_item_recur(i)),
}
}
}
8 changes: 7 additions & 1 deletion src/librustdoc/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
//! docs for usage and details.

mod conversions;
mod import_finder;

use std::cell::RefCell;
use std::fs::{create_dir_all, File};
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::rc::Rc;

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

impl<'tcx> JsonRenderer<'tcx> {
Expand Down Expand Up @@ -157,12 +159,16 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
tcx: TyCtxt<'tcx>,
) -> Result<(Self, clean::Crate), Error> {
debug!("Initializing json renderer");

let (krate, imported_items) = import_finder::get_imports(krate);

Ok((
JsonRenderer {
tcx,
index: Rc::new(RefCell::new(FxHashMap::default())),
out_path: options.output,
cache: Rc::new(cache),
imported_items,
},
krate,
))
Expand Down
28 changes: 28 additions & 0 deletions src/test/rustdoc-json/reexport/glob_collision.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Regression test for https://github.com/rust-lang/rust/issues/100973

#![feature(no_core)]
#![no_core]

// @set m1 = "$.index[*][?(@.name == 'm1' && @.kind == 'module')].id"
// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.items" []
// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.is_stripped" true
mod m1 {
pub fn f() {}
}
// @set m2 = "$.index[*][?(@.name == 'm2' && @.kind == 'module')].id"
// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.items" []
// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.is_stripped" true
mod m2 {
pub fn f(_: u8) {}
}

// @set m1_use = "$.index[*][?(@.inner.name=='m1')].id"
// @is "$.index[*][?(@.inner.name=='m1')].inner.id" $m1
// @is "$.index[*][?(@.inner.name=='m1')].inner.glob" true
pub use m1::*;
// @set m2_use = "$.index[*][?(@.inner.name=='m2')].id"
// @is "$.index[*][?(@.inner.name=='m2')].inner.id" $m2
// @is "$.index[*][?(@.inner.name=='m2')].inner.glob" true
pub use m2::*;

// @ismany "$.index[*][?(@.inner.is_crate==true)].inner.items[*]" $m1_use $m2_use
8 changes: 8 additions & 0 deletions src/test/rustdoc-json/reexport/glob_empty_mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Regression test for https://github.com/rust-lang/rust/issues/100973

// @is "$.index[*][?(@.name=='m1' && @.kind == 'module')].inner.is_stripped" true
// @set m1 = "$.index[*][?(@.name=='m1')].id"
mod m1 {}

// @is "$.index[*][?(@.inner.name=='m1' && @.kind=='import')].inner.id" $m1
pub use m1::*;
3 changes: 1 addition & 2 deletions src/test/rustdoc-json/reexport/in_root_and_mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![feature(no_core)]
#![no_core]

// @is "$.index[*][?(@.name=='foo')].kind" \"module\"
// @is "$.index[*][?(@.name=='foo')].inner.is_stripped" "true"
// @!has "$.index[*][?(@.name=='foo')]"
mod foo {
// @has "$.index[*][?(@.name=='Foo')]"
pub struct Foo;
Expand Down
14 changes: 14 additions & 0 deletions src/test/rustdoc-json/reexport/mod_not_included.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Regression test for https://github.com/rust-lang/rust/issues/101103

#![feature(no_core)]
#![no_core]

mod m1 {
pub fn x() {}
}

pub use m1::x;

// @has "$.index[*][?(@.name=='x' && @.kind=='function')]"
// @has "$.index[*][?(@.kind=='import' && @.inner.name=='x')].inner.source" '"m1::x"'
// @!has "$.index[*][?(@.name=='m1')]"
3 changes: 1 addition & 2 deletions src/test/rustdoc-json/reexport/private_two_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
#![no_core]
#![feature(no_core)]

// @is "$.index[*][?(@.name=='style')].kind" \"module\"
// @is "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
// @!has "$.index[*][?(@.name=='style')]"
mod style {
// @set color_struct_id = "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
pub struct Color;
Expand Down
3 changes: 1 addition & 2 deletions src/test/rustdoc-json/reexport/rename_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
#![no_core]
#![feature(no_core)]

// @is "$.index[*][?(@.name=='inner')].kind" \"module\"
// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
// @!has "$.index[*][?(@.kind=='inner')]"
mod inner {
// @has "$.index[*][?(@.name=='Public')]"
pub struct Public;
Expand Down
5 changes: 2 additions & 3 deletions src/test/rustdoc-json/reexport/simple_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
#![no_core]
#![feature(no_core)]

// @is "$.index[*][?(@.name=='inner')].kind" \"module\"
// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
// @!has "$.index[*][?(@.name=='inner')]"
mod inner {
// @set pub_id = "$.index[*][?(@.name=='Public')].id"
pub struct Public;
}

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

// @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
// @ismany "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
2 changes: 1 addition & 1 deletion src/test/rustdoc-json/stripped_modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod pub_inner_unreachable {
pub fn pub_inner_1() {}
}

// @has "$.index[*][?(@.name=='pub_inner_reachable')]"
// @!has "$.index[*][?(@.name=='pub_inner_reachable')]"
mod pub_inner_reachable {
// @has "$.index[*][?(@.name=='pub_inner_2')]"
pub fn pub_inner_2() {}
Expand Down