@@ -14,17 +14,19 @@ pub(crate) struct Stripper<'a> {
1414 pub ( crate ) is_json_output : bool ,
1515}
1616
17- impl < ' a > Stripper < ' a > {
18- // We need to handle this differently for the JSON output because some non exported items could
19- // be used in public API. And so, we need these items as well. `is_exported` only checks if they
20- // are in the public API, which is not enough.
21- #[ inline]
22- fn is_item_reachable ( & self , item_id : ItemId ) -> bool {
23- if self . is_json_output {
24- self . access_levels . is_reachable ( item_id. expect_def_id ( ) )
25- } else {
26- self . access_levels . is_exported ( item_id. expect_def_id ( ) )
27- }
17+ // We need to handle this differently for the JSON output because some non exported items could
18+ // be used in public API. And so, we need these items as well. `is_exported` only checks if they
19+ // are in the public API, which is not enough.
20+ #[ inline]
21+ fn is_item_reachable (
22+ is_json_output : bool ,
23+ access_levels : & AccessLevels < DefId > ,
24+ item_id : ItemId ,
25+ ) -> bool {
26+ if is_json_output {
27+ access_levels. is_reachable ( item_id. expect_def_id ( ) )
28+ } else {
29+ access_levels. is_exported ( item_id. expect_def_id ( ) )
2830 }
2931}
3032
@@ -61,7 +63,9 @@ impl<'a> DocFolder for Stripper<'a> {
6163 | clean:: MacroItem ( ..)
6264 | clean:: ForeignTypeItem => {
6365 let item_id = i. item_id ;
64- if item_id. is_local ( ) && !self . is_item_reachable ( item_id) {
66+ if item_id. is_local ( )
67+ && !is_item_reachable ( self . is_json_output , self . access_levels , item_id)
68+ {
6569 debug ! ( "Stripper: stripping {:?} {:?}" , i. type_( ) , i. name) ;
6670 return None ;
6771 }
@@ -133,15 +137,36 @@ impl<'a> DocFolder for Stripper<'a> {
133137pub ( crate ) struct ImplStripper < ' a > {
134138 pub ( crate ) retained : & ' a ItemIdSet ,
135139 pub ( crate ) cache : & ' a Cache ,
140+ pub ( crate ) is_json_output : bool ,
141+ pub ( crate ) document_private : bool ,
136142}
137143
138144impl < ' a > DocFolder for ImplStripper < ' a > {
139145 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
140146 if let clean:: ImplItem ( ref imp) = * i. kind {
141147 // Impl blocks can be skipped if they are: empty; not a trait impl; and have no
142148 // documentation.
143- if imp. trait_ . is_none ( ) && imp. items . is_empty ( ) && i. doc_value ( ) . is_none ( ) {
144- return None ;
149+ //
150+ // There is one special case: if the impl block contains only private items.
151+ if imp. trait_ . is_none ( ) {
152+ // If the only items present are private ones and we're not rendering private items,
153+ // we don't document it.
154+ if !imp. items . is_empty ( )
155+ && !self . document_private
156+ && imp. items . iter ( ) . all ( |i| {
157+ let item_id = i. item_id ;
158+ item_id. is_local ( )
159+ && !is_item_reachable (
160+ self . is_json_output ,
161+ & self . cache . access_levels ,
162+ item_id,
163+ )
164+ } )
165+ {
166+ return None ;
167+ } else if imp. items . is_empty ( ) && i. doc_value ( ) . is_none ( ) {
168+ return None ;
169+ }
145170 }
146171 if let Some ( did) = imp. for_ . def_id ( self . cache ) {
147172 if did. is_local ( ) && !imp. for_ . is_assoc_ty ( ) && !self . retained . contains ( & did. into ( ) )
0 commit comments