@@ -7,7 +7,7 @@ use crate::core::DocContext;
7
7
use crate :: formats:: cache:: Cache ;
8
8
use crate :: visit:: DocVisitor ;
9
9
10
- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
10
+ use rustc_data_structures:: fx:: FxHashMap ;
11
11
use rustc_hir:: def_id:: DefId ;
12
12
use rustc_middle:: ty:: DefIdTree ;
13
13
use rustc_span:: symbol:: sym;
@@ -25,14 +25,6 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
25
25
synth. impls
26
26
} ) ;
27
27
28
- let prims: FxHashSet < PrimitiveType > = krate. primitives . iter ( ) . map ( |p| p. 1 ) . collect ( ) ;
29
-
30
- let crate_items = {
31
- let mut coll = ItemCollector :: new ( ) ;
32
- cx. sess ( ) . time ( "collect_items_for_trait_impls" , || coll. visit_crate ( & krate) ) ;
33
- coll. items
34
- } ;
35
-
36
28
let mut new_items = Vec :: new ( ) ;
37
29
38
30
// External trait impls.
@@ -58,28 +50,20 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
58
50
}
59
51
} ) ;
60
52
61
- let mut cleaner = BadImplStripper { prims, items : crate_items, cache : & cx. cache } ;
62
53
let mut type_did_to_deref_target: FxHashMap < DefId , & Type > = FxHashMap :: default ( ) ;
63
54
64
55
// Follow all `Deref` targets of included items and recursively add them as valid
65
- fn add_deref_target (
66
- cx : & DocContext < ' _ > ,
67
- map : & FxHashMap < DefId , & Type > ,
68
- cleaner : & mut BadImplStripper < ' _ > ,
69
- type_did : DefId ,
70
- ) {
56
+ fn add_deref_target ( cx : & DocContext < ' _ > , map : & FxHashMap < DefId , & Type > , type_did : DefId ) {
71
57
if let Some ( target) = map. get ( & type_did) {
72
58
debug ! ( "add_deref_target: type {:?}, target {:?}" , type_did, target) ;
73
- if let Some ( target_prim) = target. primitive_type ( ) {
74
- cleaner. prims . insert ( target_prim) ;
59
+ if let Some ( _) = target. primitive_type ( ) {
75
60
} else if let Some ( target_did) = target. def_id ( & cx. cache ) {
76
61
// `impl Deref<Target = S> for S`
77
62
if target_did == type_did {
78
63
// Avoid infinite cycles
79
64
return ;
80
65
}
81
- cleaner. items . insert ( target_did. into ( ) ) ;
82
- add_deref_target ( cx, map, cleaner, target_did) ;
66
+ add_deref_target ( cx, map, target_did) ;
83
67
}
84
68
}
85
69
}
@@ -88,42 +72,30 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
88
72
for it in & new_items {
89
73
if let ImplItem ( Impl { ref for_, ref trait_, ref items, .. } ) = * it. kind {
90
74
if trait_. as_ref ( ) . map ( |t| t. def_id ( ) ) == cx. tcx . lang_items ( ) . deref_trait ( )
91
- && cleaner . keep_impl ( for_, true )
75
+ && keep_impl ( for_, & cx . cache )
92
76
{
93
- let target = items
77
+ let Some ( target) = items
94
78
. iter ( )
95
79
. find_map ( |item| match * item. kind {
96
80
AssocTypeItem ( ref t, _) => Some ( & t. type_ ) ,
97
81
_ => None ,
98
- } )
99
- . expect ( "Deref impl without Target type" ) ;
82
+ } ) else { continue } ;
100
83
101
- if let Some ( prim) = target. primitive_type ( ) {
102
- cleaner. prims . insert ( prim) ;
103
- } else if let Some ( did) = target. def_id ( & cx. cache ) {
104
- cleaner. items . insert ( did. into ( ) ) ;
105
- }
106
84
if let Some ( for_did) = for_. def_id ( & cx. cache ) {
107
85
if type_did_to_deref_target. insert ( for_did, target) . is_none ( ) {
108
86
// Since only the `DefId` portion of the `Type` instances is known to be same for both the
109
87
// `Deref` target type and the impl for type positions, this map of types is keyed by
110
88
// `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
111
- if cleaner. keep_impl_with_def_id ( for_did. into ( ) ) {
112
- add_deref_target ( cx, & type_did_to_deref_target, & mut cleaner, for_did) ;
113
- }
89
+ add_deref_target ( cx, & type_did_to_deref_target, for_did) ;
114
90
}
115
91
}
116
92
}
117
93
}
118
94
}
119
95
120
96
new_items. retain ( |it| {
121
- if let ImplItem ( Impl { ref for_, ref trait_, ref kind, .. } ) = * it. kind {
122
- cleaner. keep_impl (
123
- for_,
124
- trait_. as_ref ( ) . map ( |t| t. def_id ( ) ) == cx. tcx . lang_items ( ) . deref_trait ( ) ,
125
- ) || trait_. as_ref ( ) . map_or ( false , |t| cleaner. keep_impl_with_def_id ( t. def_id ( ) . into ( ) ) )
126
- || kind. is_blanket ( )
97
+ if let ImplItem ( Impl { ref for_, ref kind, .. } ) = * it. kind {
98
+ keep_impl ( for_, & cx. cache ) || kind. is_blanket ( )
127
99
} else {
128
100
true
129
101
}
@@ -186,46 +158,15 @@ impl<'a, 'tcx> DocVisitor for SyntheticImplCollector<'a, 'tcx> {
186
158
}
187
159
}
188
160
189
- #[ derive( Default ) ]
190
- struct ItemCollector {
191
- items : FxHashSet < ItemId > ,
192
- }
193
-
194
- impl ItemCollector {
195
- fn new ( ) -> Self {
196
- Self :: default ( )
197
- }
198
- }
199
-
200
- impl DocVisitor for ItemCollector {
201
- fn visit_item ( & mut self , i : & Item ) {
202
- self . items . insert ( i. item_id ) ;
203
-
204
- self . visit_item_recur ( i)
205
- }
206
- }
207
-
208
- struct BadImplStripper < ' a > {
209
- prims : FxHashSet < PrimitiveType > ,
210
- items : FxHashSet < ItemId > ,
211
- cache : & ' a Cache ,
212
- }
213
-
214
- impl < ' a > BadImplStripper < ' a > {
215
- fn keep_impl ( & self , ty : & Type , is_deref : bool ) -> bool {
216
- if let Generic ( _) = ty {
217
- // keep impls made on generics
218
- true
219
- } else if let Some ( prim) = ty. primitive_type ( ) {
220
- self . prims . contains ( & prim)
221
- } else if let Some ( did) = ty. def_id ( self . cache ) {
222
- is_deref || self . keep_impl_with_def_id ( did. into ( ) )
223
- } else {
224
- false
225
- }
226
- }
227
-
228
- fn keep_impl_with_def_id ( & self , item_id : ItemId ) -> bool {
229
- self . items . contains ( & item_id)
161
+ fn keep_impl ( ty : & Type , cache : & Cache ) -> bool {
162
+ if let Generic ( _) = ty {
163
+ // keep impls made on generics
164
+ true
165
+ } else if let Some ( _) = ty. primitive_type ( ) {
166
+ true
167
+ } else if let Some ( _) = ty. def_id ( cache) {
168
+ true
169
+ } else {
170
+ false
230
171
}
231
172
}
0 commit comments