@@ -59,57 +59,74 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
5959 self . is_in_hidden_item = prev;
6060 ret
6161 }
62+
63+ /// In case `i` is a non-hidden impl block, then we special-case it by changing the value
64+ /// of `is_in_hidden_item` to `true` because the impl children inherit its visibility.
65+ fn recurse_in_impl ( & mut self , i : Item ) -> Item {
66+ let prev = mem:: replace ( & mut self . is_in_hidden_item , false ) ;
67+ let ret = self . fold_item_recur ( i) ;
68+ self . is_in_hidden_item = prev;
69+ ret
70+ }
6271}
6372
6473impl < ' a , ' tcx > DocFolder for Stripper < ' a , ' tcx > {
6574 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
6675 let has_doc_hidden = i. attrs . lists ( sym:: doc) . has_word ( sym:: hidden) ;
67- let mut is_hidden = self . is_in_hidden_item || has_doc_hidden;
68- if !is_hidden && i. inline_stmt_id . is_none ( ) {
69- // We don't need to check if it's coming from a reexport since the reexport itself was
70- // already checked.
71- is_hidden = i
72- . item_id
73- . as_def_id ( )
74- . and_then ( |def_id| def_id. as_local ( ) )
75- . map ( |def_id| inherits_doc_hidden ( self . tcx , def_id) )
76- . unwrap_or ( false ) ;
76+ let is_impl = matches ! ( * i. kind, clean:: ImplItem ( ..) ) ;
77+ let mut is_hidden = has_doc_hidden;
78+ if !is_impl {
79+ is_hidden = self . is_in_hidden_item || has_doc_hidden;
80+ if !is_hidden && i. inline_stmt_id . is_none ( ) {
81+ // We don't need to check if it's coming from a reexport since the reexport itself was
82+ // already checked.
83+ is_hidden = i
84+ . item_id
85+ . as_def_id ( )
86+ . and_then ( |def_id| def_id. as_local ( ) )
87+ . map ( |def_id| inherits_doc_hidden ( self . tcx , def_id) )
88+ . unwrap_or ( false ) ;
89+ }
7790 }
78- if is_hidden {
79- debug ! ( "strip_hidden: stripping {:?} {:?}" , i. type_( ) , i. name) ;
80- // Use a dedicated hidden item for fields, variants, and modules.
81- // We need to keep private fields and variants, so that the docs
82- // can show a placeholder "// some variants omitted". We need to keep
83- // private modules, because they can contain impl blocks, and impl
84- // block privacy is inherited from the type and trait, not from the
85- // module it's defined in. Both of these are marked "stripped," and
86- // not included in the final docs, but since they still have an effect
87- // on the final doc, cannot be completely removed from the Clean IR.
88- return match * i. kind {
89- clean:: StructFieldItem ( ..) | clean:: ModuleItem ( ..) | clean:: VariantItem ( ..) => {
90- // We need to recurse into stripped modules to
91- // strip things like impl methods but when doing so
92- // we must not add any items to the `retained` set.
93- let old = mem:: replace ( & mut self . update_retained , false ) ;
94- let ret = strip_item ( self . set_is_in_hidden_item_and_fold ( true , i) ) ;
95- self . update_retained = old;
96- Some ( ret)
97- }
98- _ => {
99- let ret = self . set_is_in_hidden_item_and_fold ( true , i) ;
100- if has_doc_hidden {
101- // If the item itself has `#[doc(hidden)]`, then we simply remove it.
102- None
103- } else {
104- // However if it's a "descendant" of a `#[doc(hidden)]` item, then we strip it.
105- Some ( strip_item ( ret) )
106- }
107- }
108- } ;
91+ if !is_hidden {
92+ if self . update_retained {
93+ self . retained . insert ( i. item_id ) ;
94+ }
95+ return Some ( if is_impl {
96+ self . recurse_in_impl ( i)
97+ } else {
98+ self . set_is_in_hidden_item_and_fold ( false , i)
99+ } ) ;
109100 }
110- if self . update_retained {
111- self . retained . insert ( i. item_id ) ;
101+ debug ! ( "strip_hidden: stripping {:?} {:?}" , i. type_( ) , i. name) ;
102+ // Use a dedicated hidden item for fields, variants, and modules.
103+ // We need to keep private fields and variants, so that the docs
104+ // can show a placeholder "// some variants omitted". We need to keep
105+ // private modules, because they can contain impl blocks, and impl
106+ // block privacy is inherited from the type and trait, not from the
107+ // module it's defined in. Both of these are marked "stripped," and
108+ // not included in the final docs, but since they still have an effect
109+ // on the final doc, cannot be completely removed from the Clean IR.
110+ match * i. kind {
111+ clean:: StructFieldItem ( ..) | clean:: ModuleItem ( ..) | clean:: VariantItem ( ..) => {
112+ // We need to recurse into stripped modules to
113+ // strip things like impl methods but when doing so
114+ // we must not add any items to the `retained` set.
115+ let old = mem:: replace ( & mut self . update_retained , false ) ;
116+ let ret = strip_item ( self . set_is_in_hidden_item_and_fold ( true , i) ) ;
117+ self . update_retained = old;
118+ Some ( ret)
119+ }
120+ _ => {
121+ let ret = self . set_is_in_hidden_item_and_fold ( true , i) ;
122+ if has_doc_hidden {
123+ // If the item itself has `#[doc(hidden)]`, then we simply remove it.
124+ None
125+ } else {
126+ // However if it's a "descendant" of a `#[doc(hidden)]` item, then we strip it.
127+ Some ( strip_item ( ret) )
128+ }
129+ }
112130 }
113- Some ( self . set_is_in_hidden_item_and_fold ( is_hidden, i) )
114131 }
115132}
0 commit comments