about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume.gomez@huawei.com>2023-05-30 16:31:40 +0200
committerGuillaume Gomez <guillaume.gomez@huawei.com>2023-05-30 20:27:53 +0200
commit5528757ffecd11f4f63cf37209382dfdccc522c2 (patch)
tree4c59c10a0c9837d1700a03fc5419be38b442605f
parent3266c36624e804f9f086ebd40db19039b55a4ec1 (diff)
downloadrust-5528757ffecd11f4f63cf37209382dfdccc522c2.tar.gz
rust-5528757ffecd11f4f63cf37209382dfdccc522c2.zip
Fix re-export of doc hidden item inside private item not displayed
-rw-r--r--src/librustdoc/visit_ast.rs57
1 files changed, 32 insertions, 25 deletions
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 6b7ad4cf21a..abb9229fbd5 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -267,6 +267,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
             || use_attrs.lists(sym::doc).has_word(sym::hidden);
 
+        if is_no_inline {
+            return false;
+        }
+
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation -- a previously unreachable item can be
         // made reachable by cross-crate inlining which we're checking here.
@@ -281,31 +285,38 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         };
 
         let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
-        let is_hidden = inherits_doc_hidden(tcx, res_did, None);
+        let is_hidden = tcx.is_doc_hidden(ori_res_did);
+        let item = tcx.hir().get_by_def_id(res_did);
 
-        // Only inline if requested or if the item would otherwise be stripped.
-        if (!please_inline && !is_private && !is_hidden) || is_no_inline {
-            return false;
-        }
-
-        if !please_inline &&
-            let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
+        if !please_inline {
+            let inherits_hidden = inherits_doc_hidden(tcx, res_did, None);
+            // Only inline if requested or if the item would otherwise be stripped.
+            //
+            // If it's a doc hidden module, we need to keep it in case some of its inner items
+            // are re-exported.
+            if (!is_private && !inherits_hidden) || (
+                is_hidden &&
+                !matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_), .. }))
+            ) {
+                return false;
+            } else if let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
                 .flat_map(|reexport| reexport.id()).map(|id| id.expect_local())
                 .chain(iter::once(res_did)).nth(1) &&
-            item_def_id != def_id &&
-            self
-                .cx
-                .cache
-                .effective_visibilities
-                .is_directly_public(tcx, item_def_id.to_def_id()) &&
-            !inherits_doc_hidden(tcx, item_def_id, None)
-        {
-            // The imported item is public and not `doc(hidden)` so no need to inline it.
-            return false;
+                item_def_id != def_id &&
+                self
+                    .cx
+                    .cache
+                    .effective_visibilities
+                    .is_directly_public(tcx, item_def_id.to_def_id()) &&
+                !inherits_doc_hidden(tcx, item_def_id, None)
+            {
+                // The imported item is public and not `doc(hidden)` so no need to inline it.
+                return false;
+            }
         }
 
         let is_bang_macro = matches!(
-            tcx.hir().get_by_def_id(res_did),
+            item,
             Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. })
         );
 
@@ -317,12 +328,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             // Bang macros are handled a bit on their because of how they are handled by the
             // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
             // `#[doc(inline)]`, then we don't inline it.
-            Node::Item(_)
-                if is_bang_macro
-                    && !please_inline
-                    && renamed.is_some()
-                    && self.cx.tcx.is_doc_hidden(ori_res_did) =>
-            {
+            Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
                 return false;
             }
             Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
@@ -455,6 +461,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                             is_glob,
                             please_inline,
                         ) {
+                            debug!("Inlining {:?}", item.owner_id.def_id);
                             continue;
                         }
                     }