@@ -35,6 +35,9 @@ pub(crate) struct Module<'hir> {
3535 ( LocalDefId , Option < Symbol > ) ,
3636 ( & ' hir hir:: Item < ' hir > , Option < Symbol > , Option < LocalDefId > ) ,
3737 > ,
38+ /// Same as for `items`.
39+ pub ( crate ) inlined_foreigns :
40+ FxIndexMap < ( DefId , Option < Symbol > ) , ( Res , Option < Symbol > , LocalDefId ) > ,
3841 pub ( crate ) foreigns : Vec < ( & ' hir hir:: ForeignItem < ' hir > , Option < Symbol > ) > ,
3942}
4043
@@ -54,6 +57,7 @@ impl Module<'_> {
5457 import_id,
5558 mods : Vec :: new ( ) ,
5659 items : FxIndexMap :: default ( ) ,
60+ inlined_foreigns : FxIndexMap :: default ( ) ,
5761 foreigns : Vec :: new ( ) ,
5862 }
5963 }
@@ -272,21 +276,30 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
272276 return false ;
273277 }
274278
275- // For cross-crate impl inlining we need to know whether items are
276- // reachable in documentation -- a previously unreachable item can be
277- // made reachable by cross-crate inlining which we're checking here.
278- // (this is done here because we need to know this upfront).
279- if !ori_res_did. is_local ( ) && !is_no_inline {
280- crate :: visit_lib:: lib_embargo_visit_item ( self . cx , ori_res_did) ;
281- return false ;
282- }
283-
279+ let is_hidden = !document_hidden && tcx. is_doc_hidden ( ori_res_did) ;
284280 let Some ( res_did) = ori_res_did. as_local ( ) else {
285- return false ;
281+ // For cross-crate impl inlining we need to know whether items are
282+ // reachable in documentation -- a previously unreachable item can be
283+ // made reachable by cross-crate inlining which we're checking here.
284+ // (this is done here because we need to know this upfront).
285+ crate :: visit_lib:: lib_embargo_visit_item ( self . cx , ori_res_did) ;
286+ if is_hidden {
287+ return false ;
288+ }
289+ // We store inlined foreign items otherwise, it'd mean that the `use` item would be kept
290+ // around. It's not a problem unless this `use` imports both a local AND a foreign item.
291+ // If a local item is inlined, its `use` is not supposed to still be around in `clean`,
292+ // which would make appear the `use` in the generated documentation like the local item
293+ // was not inlined even though it actually was.
294+ self . modules
295+ . last_mut ( )
296+ . unwrap ( )
297+ . inlined_foreigns
298+ . insert ( ( ori_res_did, renamed) , ( res, renamed, def_id) ) ;
299+ return true ;
286300 } ;
287301
288302 let is_private = !self . cx . cache . effective_visibilities . is_directly_public ( tcx, ori_res_did) ;
289- let is_hidden = !document_hidden && tcx. is_doc_hidden ( ori_res_did) ;
290303 let item = tcx. hir ( ) . get_by_def_id ( res_did) ;
291304
292305 if !please_inline {
@@ -314,7 +327,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
314327 return false ;
315328 }
316329
317- let inlined = match tcx . hir ( ) . get_by_def_id ( res_did ) {
330+ let inlined = match item {
318331 // Bang macros are handled a bit on their because of how they are handled by the
319332 // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
320333 // `#[doc(inline)]`, then we don't inline it.
@@ -346,7 +359,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
346359 } ;
347360 self . view_item_stack . remove ( & res_did) ;
348361 if inlined {
349- self . cx . cache . inlined_items . insert ( res_did . to_def_id ( ) ) ;
362+ self . cx . cache . inlined_items . insert ( ori_res_did ) ;
350363 }
351364 inlined
352365 }
@@ -483,7 +496,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
483496 continue ;
484497 }
485498 }
486-
487499 self . add_to_current_mod ( item, renamed, import_id) ;
488500 }
489501 }
0 commit comments