11//! Strip all doc(hidden) items from the output.
22
3+ use rustc_hir:: def_id:: LocalDefId ;
34use rustc_middle:: ty:: TyCtxt ;
45use rustc_span:: symbol:: sym;
56use std:: mem;
@@ -29,6 +30,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
2930 update_retained : true ,
3031 tcx : cx. tcx ,
3132 is_in_hidden_item : false ,
33+ last_reexport : None ,
3234 } ;
3335 stripper. fold_crate ( krate)
3436 } ;
@@ -49,13 +51,24 @@ struct Stripper<'a, 'tcx> {
4951 update_retained : bool ,
5052 tcx : TyCtxt < ' tcx > ,
5153 is_in_hidden_item : bool ,
54+ last_reexport : Option < LocalDefId > ,
5255}
5356
5457impl < ' a , ' tcx > Stripper < ' a , ' tcx > {
58+ fn set_last_reexport_then_fold_item ( & mut self , i : Item ) -> Item {
59+ let prev_from_reexport = self . last_reexport ;
60+ if i. inline_stmt_id . is_some ( ) {
61+ self . last_reexport = i. item_id . as_def_id ( ) . and_then ( |def_id| def_id. as_local ( ) ) ;
62+ }
63+ let ret = self . fold_item_recur ( i) ;
64+ self . last_reexport = prev_from_reexport;
65+ ret
66+ }
67+
5568 fn set_is_in_hidden_item_and_fold ( & mut self , is_in_hidden_item : bool , i : Item ) -> Item {
5669 let prev = self . is_in_hidden_item ;
5770 self . is_in_hidden_item |= is_in_hidden_item;
58- let ret = self . fold_item_recur ( i) ;
71+ let ret = self . set_last_reexport_then_fold_item ( i) ;
5972 self . is_in_hidden_item = prev;
6073 ret
6174 }
@@ -64,7 +77,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
6477 /// of `is_in_hidden_item` to `true` because the impl children inherit its visibility.
6578 fn recurse_in_impl_or_exported_macro ( & mut self , i : Item ) -> Item {
6679 let prev = mem:: replace ( & mut self . is_in_hidden_item , false ) ;
67- let ret = self . fold_item_recur ( i) ;
80+ let ret = self . set_last_reexport_then_fold_item ( i) ;
6881 self . is_in_hidden_item = prev;
6982 ret
7083 }
@@ -86,13 +99,20 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
8699 if !is_impl_or_exported_macro {
87100 is_hidden = self . is_in_hidden_item || has_doc_hidden;
88101 if !is_hidden && i. inline_stmt_id . is_none ( ) {
89- // We don't need to check if it's coming from a reexport since the reexport itself was
90- // already checked.
102+ // `i.inline_stmt_id` is `Some` if the item is directly reexported. If it is, we
103+ // don't need to check it, because the reexport itself was already checked.
104+ //
105+ // If this item is the child of a reexported module, `self.last_reexport` will be
106+ // `Some` even though `i.inline_stmt_id` is `None`. Hiddenness inheritance needs to
107+ // account for the possibility that an item's true parent module is hidden, but it's
108+ // inlined into a visible module true. This code shouldn't be reachable if the
109+ // module's reexport is itself hidden, for the same reason it doesn't need to be
110+ // checked if `i.inline_stmt_id` is Some: hidden reexports are never inlined.
91111 is_hidden = i
92112 . item_id
93113 . as_def_id ( )
94114 . and_then ( |def_id| def_id. as_local ( ) )
95- . map ( |def_id| inherits_doc_hidden ( self . tcx , def_id) )
115+ . map ( |def_id| inherits_doc_hidden ( self . tcx , def_id, self . last_reexport ) )
96116 . unwrap_or ( false ) ;
97117 }
98118 }
0 commit comments