@@ -35,6 +35,9 @@ pub(crate) struct Module<'hir> {
35
35
( LocalDefId , Option < Symbol > ) ,
36
36
( & ' hir hir:: Item < ' hir > , Option < Symbol > , Option < LocalDefId > ) ,
37
37
> ,
38
+ /// Same as for `items`.
39
+ pub ( crate ) inlined_foreigns :
40
+ FxIndexMap < ( DefId , Option < Symbol > ) , ( Res , Option < Symbol > , LocalDefId ) > ,
38
41
pub ( crate ) foreigns : Vec < ( & ' hir hir:: ForeignItem < ' hir > , Option < Symbol > ) > ,
39
42
}
40
43
@@ -54,6 +57,7 @@ impl Module<'_> {
54
57
import_id,
55
58
mods : Vec :: new ( ) ,
56
59
items : FxIndexMap :: default ( ) ,
60
+ inlined_foreigns : FxIndexMap :: default ( ) ,
57
61
foreigns : Vec :: new ( ) ,
58
62
}
59
63
}
@@ -272,21 +276,30 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
272
276
return false ;
273
277
}
274
278
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) ;
284
280
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 ;
286
300
} ;
287
301
288
302
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) ;
290
303
let item = tcx. hir ( ) . get_by_def_id ( res_did) ;
291
304
292
305
if !please_inline {
@@ -314,7 +327,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
314
327
return false ;
315
328
}
316
329
317
- let inlined = match tcx . hir ( ) . get_by_def_id ( res_did ) {
330
+ let inlined = match item {
318
331
// Bang macros are handled a bit on their because of how they are handled by the
319
332
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
320
333
// `#[doc(inline)]`, then we don't inline it.
@@ -346,7 +359,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
346
359
} ;
347
360
self . view_item_stack . remove ( & res_did) ;
348
361
if inlined {
349
- self . cx . cache . inlined_items . insert ( res_did . to_def_id ( ) ) ;
362
+ self . cx . cache . inlined_items . insert ( ori_res_did ) ;
350
363
}
351
364
inlined
352
365
}
@@ -483,7 +496,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
483
496
continue ;
484
497
}
485
498
}
486
-
487
499
self . add_to_current_mod ( item, renamed, import_id) ;
488
500
}
489
501
}
0 commit comments