Skip to content

Commit

Permalink
Rollup merge of rust-lang#101106 - aDotInTheVoid:rdj-stripped-mod, r=…
Browse files Browse the repository at this point in the history
…GuillaumeGomez

Rustdoc-Json: Retain Stripped Modules when they are imported, not when they have items

Fixes rust-lang#101103
Fixes rust-lang#100973

r? `@GuillaumeGomez`
  • Loading branch information
matthiaskrgr authored Aug 28, 2022
2 parents 2c3a10d + 785101d commit b7b98e2
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 13 deletions.
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 https://github.com/rust-lang/rust/issues/100973 and
/// 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

0 comments on commit b7b98e2

Please sign in to comment.