Repository: rust
Issue: [rustdoc-json] Foreign items that are only re-exported are no longer included in the index
Labels: T-rustdoc,C-bug,requires-nightly,A-rustdoc-json

PR https://github.com/rust-lang/rust/pull/99287 changed the behavior of the JSON output of rustdoc to no longer do inlining of re-export as it was causing many problems. However the new behavior do not account for foreign items that are only re-exported as they are no longer included in the index.

We should fix this by re-introducing them in the index. But how ? I tried hacking around by doing partial-inlining but this will just re-introduce the problems we has before. I someone wants to build on what I did here is the code:

<details>

```diff
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index ce10ca9aa3d..5274a211986 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -153,7 +153,18 @@ pub(crate) fn try_inline_glob(
     match res {
         Res::Def(DefKind::Mod, did) => {
             let m = build_module(cx, did, visited);
-            Some(m.items)
+            if cx.output_format.is_json() {
+                let m = clean::ModuleItem(m);
+                let m = clean::Item::from_def_id_and_parts(
+                    did,
+                    None,
+                    m,
+                    cx,
+                );
+                Some(vec![m])
+            } else {
+                Some(m.items)
+            }
         }
         // glob imports on things like enums aren't inlined even for local exports, so just bail
         _ => None,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9865601da5f..53a3246ae87 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2152,8 +2152,7 @@ fn clean_use_statement<'tcx>(
     // forcefully don't inline if this is not public or if the
     // #[doc(no_inline)] attribute is present.
     // Don't inline doc(hidden) imports so they can be stripped at a later stage.
-    let mut denied = cx.output_format.is_json()
-        || !(visibility.is_public()
+    let mut denied = !(visibility.is_public()
             || (cx.render_options.document_private && is_visible_from_parent_mod))
         || pub_underscore
         || attrs.iter().any(|a| {
@@ -2170,11 +2169,16 @@ fn clean_use_statement<'tcx>(
     // Also check whether imports were asked to be inlined, in case we're trying to re-export a
     // crate in Rust 2018+
     let path = path.clean(cx);
+    let mut inner_items = None;
     let inner = if kind == hir::UseKind::Glob {
         if !denied {
             let mut visited = FxHashSet::default();
             if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
-                return items;
+                if cx.output_format.is_json() {
+                    inner_items = Some(items);
+                } else {
+                    return items;
+                }
             }
         }
         Import::new_glob(resolve_use_source(cx, path), true)
@@ -2204,16 +2208,25 @@ fn clean_use_statement<'tcx>(
                 items.push(Item::from_def_id_and_parts(
                     import_def_id,
                     None,
-                    ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
+                    ImportItem(Import::new_simple(name, resolve_use_source(cx, path.clone()), false)),
                     cx,
                 ));
-                return items;
+                if cx.output_format.is_json() {
+                    inner_items = Some(items);
+                } else {
+                    return items;
+                }
             }
         }
         Import::new_simple(name, resolve_use_source(cx, path), true)
     };
 
-    vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)]
+    if let Some(mut inner_items) = inner_items {
+        inner_items.push(Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx));
+        inner_items
+    } else {
+        vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)]
+    }
 }
 
 fn clean_maybe_renamed_foreign_item<'tcx>(
```

</details>

cc @aDotInTheVoid @CraftSpider @Enselic
@rustbot labels +A-rustdoc-json +T-rustdoc +requires-nightly