@@ -12,6 +12,7 @@ use rustc::hir::def_id::DefId;
1212use rustc:: middle:: privacy:: AccessLevels ;
1313use rustc:: util:: nodemap:: DefIdSet ;
1414use std:: cmp;
15+ use std:: mem;
1516use std:: string:: String ;
1617use std:: usize;
1718
@@ -29,7 +30,8 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
2930 // strip all #[doc(hidden)] items
3031 let krate = {
3132 struct Stripper < ' a > {
32- retained : & ' a mut DefIdSet
33+ retained : & ' a mut DefIdSet ,
34+ update_retained : bool ,
3335 }
3436 impl < ' a > fold:: DocFolder for Stripper < ' a > {
3537 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
@@ -38,17 +40,25 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
3840 // use a dedicated hidden item for given item type if any
3941 match i. inner {
4042 clean:: StructFieldItem ( ..) | clean:: ModuleItem ( ..) => {
41- return Strip ( i) . fold ( )
43+ // We need to recurse into stripped modules to
44+ // strip things like impl methods but when doing so
45+ // we must not add any items to the `retained` set.
46+ let old = mem:: replace ( & mut self . update_retained , false ) ;
47+ let ret = Strip ( self . fold_item_recur ( i) . unwrap ( ) ) . fold ( ) ;
48+ self . update_retained = old;
49+ return ret;
4250 }
4351 _ => return None ,
4452 }
4553 } else {
46- self . retained . insert ( i. def_id ) ;
54+ if self . update_retained {
55+ self . retained . insert ( i. def_id ) ;
56+ }
4757 }
4858 self . fold_item_recur ( i)
4959 }
5060 }
51- let mut stripper = Stripper { retained : & mut retained } ;
61+ let mut stripper = Stripper { retained : & mut retained, update_retained : true } ;
5262 stripper. fold_crate ( krate)
5363 } ;
5464
@@ -69,6 +79,7 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
6979 let mut stripper = Stripper {
7080 retained : & mut retained,
7181 access_levels : & access_levels,
82+ update_retained : true ,
7283 } ;
7384 krate = ImportStripper . fold_crate ( stripper. fold_crate ( krate) ) ;
7485 }
@@ -81,12 +92,21 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
8192struct Stripper < ' a > {
8293 retained : & ' a mut DefIdSet ,
8394 access_levels : & ' a AccessLevels < DefId > ,
95+ update_retained : bool ,
8496}
8597
8698impl < ' a > fold:: DocFolder for Stripper < ' a > {
8799 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
88100 match i. inner {
89- clean:: StrippedItem ( ..) => return Some ( i) ,
101+ clean:: StrippedItem ( ..) => {
102+ // We need to recurse into stripped modules to strip things
103+ // like impl methods but when doing so we must not add any
104+ // items to the `retained` set.
105+ let old = mem:: replace ( & mut self . update_retained , false ) ;
106+ let ret = self . fold_item_recur ( i) ;
107+ self . update_retained = old;
108+ return ret;
109+ }
90110 // These items can all get re-exported
91111 clean:: TypedefItem ( ..) | clean:: StaticItem ( ..) |
92112 clean:: StructItem ( ..) | clean:: EnumItem ( ..) |
@@ -109,18 +129,13 @@ impl<'a> fold::DocFolder for Stripper<'a> {
109129
110130 clean:: ModuleItem ( ..) => {
111131 if i. def_id . is_local ( ) && i. visibility != Some ( clean:: Public ) {
112- return Strip ( self . fold_item_recur ( i) . unwrap ( ) ) . fold ( )
132+ let old = mem:: replace ( & mut self . update_retained , false ) ;
133+ let ret = Strip ( self . fold_item_recur ( i) . unwrap ( ) ) . fold ( ) ;
134+ self . update_retained = old;
135+ return ret;
113136 }
114137 }
115138
116- // trait impls for private items should be stripped
117- clean:: ImplItem ( clean:: Impl {
118- for_ : clean:: ResolvedPath { did, is_generic, .. } , ..
119- } ) => {
120- if did. is_local ( ) && !is_generic && !self . access_levels . is_exported ( did) {
121- return None ;
122- }
123- }
124139 // handled in the `strip-priv-imports` pass
125140 clean:: ExternCrateItem ( ..) | clean:: ImportItem ( ..) => { }
126141
@@ -152,21 +167,24 @@ impl<'a> fold::DocFolder for Stripper<'a> {
152167 } ;
153168
154169 let i = if fastreturn {
155- self . retained . insert ( i. def_id ) ;
170+ if self . update_retained {
171+ self . retained . insert ( i. def_id ) ;
172+ }
156173 return Some ( i) ;
157174 } else {
158175 self . fold_item_recur ( i)
159176 } ;
160177
161178 i. and_then ( |i| {
162179 match i. inner {
163- // emptied modules/impls have no need to exist
180+ // emptied modules have no need to exist
164181 clean:: ModuleItem ( ref m)
165182 if m. items . is_empty ( ) &&
166183 i. doc_value ( ) . is_none ( ) => None ,
167- clean:: ImplItem ( ref i) if i. items . is_empty ( ) => None ,
168184 _ => {
169- self . retained . insert ( i. def_id ) ;
185+ if self . update_retained {
186+ self . retained . insert ( i. def_id ) ;
187+ }
170188 Some ( i)
171189 }
172190 }
@@ -182,6 +200,10 @@ struct ImplStripper<'a> {
182200impl < ' a > fold:: DocFolder for ImplStripper < ' a > {
183201 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
184202 if let clean:: ImplItem ( ref imp) = i. inner {
203+ // emptied none trait impls can be stripped
204+ if imp. trait_ . is_none ( ) && imp. items . is_empty ( ) {
205+ return None ;
206+ }
185207 if let Some ( did) = imp. for_ . def_id ( ) {
186208 if did. is_local ( ) && !imp. for_ . is_generic ( ) &&
187209 !self . retained . contains ( & did)
0 commit comments