@@ -267,6 +267,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
267267 let is_no_inline = use_attrs. lists ( sym:: doc) . has_word ( sym:: no_inline)
268268 || use_attrs. lists ( sym:: doc) . has_word ( sym:: hidden) ;
269269
270+ if is_no_inline {
271+ return false ;
272+ }
273+
270274 // For cross-crate impl inlining we need to know whether items are
271275 // reachable in documentation -- a previously unreachable item can be
272276 // made reachable by cross-crate inlining which we're checking here.
@@ -281,31 +285,38 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
281285 } ;
282286
283287 let is_private = !self . cx . cache . effective_visibilities . is_directly_public ( tcx, ori_res_did) ;
284- let is_hidden = inherits_doc_hidden ( tcx, res_did, None ) ;
288+ let is_hidden = tcx. is_doc_hidden ( ori_res_did) ;
289+ let item = tcx. hir ( ) . get_by_def_id ( res_did) ;
285290
286- // Only inline if requested or if the item would otherwise be stripped.
287- if ( !please_inline && !is_private && !is_hidden) || is_no_inline {
288- return false ;
289- }
290-
291- if !please_inline &&
292- let Some ( item_def_id) = reexport_chain ( tcx, def_id, res_did) . iter ( )
291+ if !please_inline {
292+ let inherits_hidden = inherits_doc_hidden ( tcx, res_did, None ) ;
293+ // Only inline if requested or if the item would otherwise be stripped.
294+ //
295+ // If it's a doc hidden module, we need to keep it in case some of its inner items
296+ // are re-exported.
297+ if ( !is_private && !inherits_hidden) || (
298+ is_hidden &&
299+ !matches ! ( item, Node :: Item ( & hir:: Item { kind: hir:: ItemKind :: Mod ( _) , .. } ) )
300+ ) {
301+ return false ;
302+ } else if let Some ( item_def_id) = reexport_chain ( tcx, def_id, res_did) . iter ( )
293303 . flat_map ( |reexport| reexport. id ( ) ) . map ( |id| id. expect_local ( ) )
294304 . chain ( iter:: once ( res_did) ) . nth ( 1 ) &&
295- item_def_id != def_id &&
296- self
297- . cx
298- . cache
299- . effective_visibilities
300- . is_directly_public ( tcx, item_def_id. to_def_id ( ) ) &&
301- !inherits_doc_hidden ( tcx, item_def_id, None )
302- {
303- // The imported item is public and not `doc(hidden)` so no need to inline it.
304- return false ;
305+ item_def_id != def_id &&
306+ self
307+ . cx
308+ . cache
309+ . effective_visibilities
310+ . is_directly_public ( tcx, item_def_id. to_def_id ( ) ) &&
311+ !inherits_doc_hidden ( tcx, item_def_id, None )
312+ {
313+ // The imported item is public and not `doc(hidden)` so no need to inline it.
314+ return false ;
315+ }
305316 }
306317
307318 let is_bang_macro = matches ! (
308- tcx . hir ( ) . get_by_def_id ( res_did ) ,
319+ item ,
309320 Node :: Item ( & hir:: Item { kind: hir:: ItemKind :: Macro ( _, MacroKind :: Bang ) , .. } )
310321 ) ;
311322
@@ -317,12 +328,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
317328 // Bang macros are handled a bit on their because of how they are handled by the
318329 // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
319330 // `#[doc(inline)]`, then we don't inline it.
320- Node :: Item ( _)
321- if is_bang_macro
322- && !please_inline
323- && renamed. is_some ( )
324- && self . cx . tcx . is_doc_hidden ( ori_res_did) =>
325- {
331+ Node :: Item ( _) if is_bang_macro && !please_inline && renamed. is_some ( ) && is_hidden => {
326332 return false ;
327333 }
328334 Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: Mod ( ref m) , .. } ) if glob => {
@@ -455,6 +461,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
455461 is_glob,
456462 please_inline,
457463 ) {
464+ debug ! ( "Inlining {:?}" , item. owner_id. def_id) ;
458465 continue ;
459466 }
460467 }
0 commit comments