@@ -12,6 +12,7 @@ use rustc::hir::def_id::DefId;
12
12
use rustc:: middle:: privacy:: AccessLevels ;
13
13
use rustc:: util:: nodemap:: DefIdSet ;
14
14
use std:: cmp;
15
+ use std:: mem;
15
16
use std:: string:: String ;
16
17
use std:: usize;
17
18
@@ -29,7 +30,8 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
29
30
// strip all #[doc(hidden)] items
30
31
let krate = {
31
32
struct Stripper < ' a > {
32
- retained : & ' a mut DefIdSet
33
+ retained : & ' a mut DefIdSet ,
34
+ update_retained : bool ,
33
35
}
34
36
impl < ' a > fold:: DocFolder for Stripper < ' a > {
35
37
fn fold_item ( & mut self , i : Item ) -> Option < Item > {
@@ -38,17 +40,25 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
38
40
// use a dedicated hidden item for given item type if any
39
41
match i. inner {
40
42
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;
42
50
}
43
51
_ => return None ,
44
52
}
45
53
} else {
46
- self . retained . insert ( i. def_id ) ;
54
+ if self . update_retained {
55
+ self . retained . insert ( i. def_id ) ;
56
+ }
47
57
}
48
58
self . fold_item_recur ( i)
49
59
}
50
60
}
51
- let mut stripper = Stripper { retained : & mut retained } ;
61
+ let mut stripper = Stripper { retained : & mut retained, update_retained : true } ;
52
62
stripper. fold_crate ( krate)
53
63
} ;
54
64
@@ -69,6 +79,7 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
69
79
let mut stripper = Stripper {
70
80
retained : & mut retained,
71
81
access_levels : & access_levels,
82
+ update_retained : true ,
72
83
} ;
73
84
krate = ImportStripper . fold_crate ( stripper. fold_crate ( krate) ) ;
74
85
}
@@ -81,12 +92,21 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
81
92
struct Stripper < ' a > {
82
93
retained : & ' a mut DefIdSet ,
83
94
access_levels : & ' a AccessLevels < DefId > ,
95
+ update_retained : bool ,
84
96
}
85
97
86
98
impl < ' a > fold:: DocFolder for Stripper < ' a > {
87
99
fn fold_item ( & mut self , i : Item ) -> Option < Item > {
88
100
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
+ }
90
110
// These items can all get re-exported
91
111
clean:: TypedefItem ( ..) | clean:: StaticItem ( ..) |
92
112
clean:: StructItem ( ..) | clean:: EnumItem ( ..) |
@@ -109,18 +129,13 @@ impl<'a> fold::DocFolder for Stripper<'a> {
109
129
110
130
clean:: ModuleItem ( ..) => {
111
131
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;
113
136
}
114
137
}
115
138
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
- }
124
139
// handled in the `strip-priv-imports` pass
125
140
clean:: ExternCrateItem ( ..) | clean:: ImportItem ( ..) => { }
126
141
@@ -152,21 +167,24 @@ impl<'a> fold::DocFolder for Stripper<'a> {
152
167
} ;
153
168
154
169
let i = if fastreturn {
155
- self . retained . insert ( i. def_id ) ;
170
+ if self . update_retained {
171
+ self . retained . insert ( i. def_id ) ;
172
+ }
156
173
return Some ( i) ;
157
174
} else {
158
175
self . fold_item_recur ( i)
159
176
} ;
160
177
161
178
i. and_then ( |i| {
162
179
match i. inner {
163
- // emptied modules/impls have no need to exist
180
+ // emptied modules have no need to exist
164
181
clean:: ModuleItem ( ref m)
165
182
if m. items . is_empty ( ) &&
166
183
i. doc_value ( ) . is_none ( ) => None ,
167
- clean:: ImplItem ( ref i) if i. items . is_empty ( ) => None ,
168
184
_ => {
169
- self . retained . insert ( i. def_id ) ;
185
+ if self . update_retained {
186
+ self . retained . insert ( i. def_id ) ;
187
+ }
170
188
Some ( i)
171
189
}
172
190
}
@@ -182,6 +200,10 @@ struct ImplStripper<'a> {
182
200
impl < ' a > fold:: DocFolder for ImplStripper < ' a > {
183
201
fn fold_item ( & mut self , i : Item ) -> Option < Item > {
184
202
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
+ }
185
207
if let Some ( did) = imp. for_ . def_id ( ) {
186
208
if did. is_local ( ) && !imp. for_ . is_generic ( ) &&
187
209
!self . retained . contains ( & did)
0 commit comments