about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-08-29 21:12:56 +0200
committerGitHub <noreply@github.com>2022-08-29 21:12:56 +0200
commitecd908ac5e0f91923f4b0915a7ac04d7909d6e8e (patch)
treec04edb77c3d56661b6fcbcee8d6bad146976ab6b
parent3bff15b7e398852c9f55607357028f5601247115 (diff)
parent891ebf90a50d7158258b30177bbd7a555f2af0cf (diff)
downloadrust-ecd908ac5e0f91923f4b0915a7ac04d7909d6e8e.tar.gz
rust-ecd908ac5e0f91923f4b0915a7ac04d7909d6e8e.zip
Rollup merge of #101106 - aDotInTheVoid:rdj-stripped-mod, r=GuillaumeGomez
Rustdoc-Json: Retain Stripped Modules when they are imported, not when they have items

Fixes #101103
Fixes #100973

r? `@GuillaumeGomez`
-rw-r--r--src/etc/check_missing_items.py6
-rw-r--r--src/librustdoc/json/conversions.rs8
-rw-r--r--src/librustdoc/json/import_finder.rs38
-rw-r--r--src/librustdoc/json/mod.rs8
-rw-r--r--src/test/rustdoc-json/reexport/glob_collision.rs28
-rw-r--r--src/test/rustdoc-json/reexport/glob_empty_mod.rs8
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod.rs3
-rw-r--r--src/test/rustdoc-json/reexport/mod_not_included.rs14
-rw-r--r--src/test/rustdoc-json/reexport/private_two_names.rs3
-rw-r--r--src/test/rustdoc-json/reexport/rename_private.rs3
-rw-r--r--src/test/rustdoc-json/reexport/simple_private.rs5
-rw-r--r--src/test/rustdoc-json/stripped_modules.rs2
12 files changed, 113 insertions, 13 deletions
diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py
index ce06a79a21c..025f320e3a1 100644
--- a/src/etc/check_missing_items.py
+++ b/src/etc/check_missing_items.py
@@ -187,3 +187,9 @@ while work_list:
             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)
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index c4e8b6f5f84..20b9eb1c27e 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -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,
                 }
             }
diff --git a/src/librustdoc/json/import_finder.rs b/src/librustdoc/json/import_finder.rs
new file mode 100644
index 00000000000..c5c687df74f
--- /dev/null
+++ b/src/librustdoc/json/import_finder.rs
@@ -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)),
+        }
+    }
+}
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index b78f8f2b4f1..6a1409c7394 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -5,6 +5,7 @@
 //! docs for usage and details.
 
 mod conversions;
+mod import_finder;
 
 use std::cell::RefCell;
 use std::fs::{create_dir_all, File};
@@ -12,7 +13,7 @@ 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;
@@ -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> {
@@ -159,12 +161,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,
         ))
diff --git a/src/test/rustdoc-json/reexport/glob_collision.rs b/src/test/rustdoc-json/reexport/glob_collision.rs
new file mode 100644
index 00000000000..f91144dbfad
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_collision.rs
@@ -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
diff --git a/src/test/rustdoc-json/reexport/glob_empty_mod.rs b/src/test/rustdoc-json/reexport/glob_empty_mod.rs
new file mode 100644
index 00000000000..da68228352c
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_empty_mod.rs
@@ -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::*;
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod.rs b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
index 68cb694f499..7b97ebf2129 100644
--- a/src/test/rustdoc-json/reexport/in_root_and_mod.rs
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
@@ -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;
diff --git a/src/test/rustdoc-json/reexport/mod_not_included.rs b/src/test/rustdoc-json/reexport/mod_not_included.rs
new file mode 100644
index 00000000000..7b7600ef20f
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/mod_not_included.rs
@@ -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')]"
diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs
index ec78b06d09a..9858538a9d0 100644
--- a/src/test/rustdoc-json/reexport/private_two_names.rs
+++ b/src/test/rustdoc-json/reexport/private_two_names.rs
@@ -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;
diff --git a/src/test/rustdoc-json/reexport/rename_private.rs b/src/test/rustdoc-json/reexport/rename_private.rs
index 1537f834481..8fd850f9b13 100644
--- a/src/test/rustdoc-json/reexport/rename_private.rs
+++ b/src/test/rustdoc-json/reexport/rename_private.rs
@@ -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;
diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs
index 82348b383c3..d058ce0598d 100644
--- a/src/test/rustdoc-json/reexport/simple_private.rs
+++ b/src/test/rustdoc-json/reexport/simple_private.rs
@@ -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
diff --git a/src/test/rustdoc-json/stripped_modules.rs b/src/test/rustdoc-json/stripped_modules.rs
index 33e95ce69d0..d2664b49e9c 100644
--- a/src/test/rustdoc-json/stripped_modules.rs
+++ b/src/test/rustdoc-json/stripped_modules.rs
@@ -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() {}