@@ -33,21 +33,50 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
3333 coll. items
3434 } ;
3535
36- let mut new_items = Vec :: new ( ) ;
36+ let mut new_items_external = Vec :: new ( ) ;
37+ let mut new_items_local = Vec :: new ( ) ;
3738
3839 // External trait impls.
3940 cx. with_all_trait_impls ( |cx, all_trait_impls| {
4041 let _prof_timer = cx. tcx . sess . prof . generic_activity ( "build_extern_trait_impls" ) ;
4142 for & impl_def_id in all_trait_impls. iter ( ) . skip_while ( |def_id| def_id. is_local ( ) ) {
42- inline:: build_impl ( cx, None , impl_def_id, None , & mut new_items) ;
43+ inline:: build_impl ( cx, None , impl_def_id, None , & mut new_items_external) ;
44+ }
45+ } ) ;
46+
47+ // Local trait impls.
48+ cx. with_all_trait_impls ( |cx, all_trait_impls| {
49+ let _prof_timer = cx. tcx . sess . prof . generic_activity ( "build_local_trait_impls" ) ;
50+ let mut attr_buf = Vec :: new ( ) ;
51+ for & impl_def_id in all_trait_impls. iter ( ) . take_while ( |def_id| def_id. is_local ( ) ) {
52+ let mut parent = cx. tcx . parent ( impl_def_id) ;
53+ while let Some ( did) = parent {
54+ attr_buf. extend (
55+ cx. tcx
56+ . get_attrs ( did)
57+ . iter ( )
58+ . filter ( |attr| attr. has_name ( sym:: doc) )
59+ . filter ( |attr| {
60+ if let Some ( [ attr] ) = attr. meta_item_list ( ) . as_deref ( ) {
61+ attr. has_name ( sym:: cfg)
62+ } else {
63+ false
64+ }
65+ } )
66+ . cloned ( ) ,
67+ ) ;
68+ parent = cx. tcx . parent ( did) ;
69+ }
70+ inline:: build_impl ( cx, None , impl_def_id, Some ( & attr_buf) , & mut new_items_local) ;
71+ attr_buf. clear ( ) ;
4372 }
4473 } ) ;
4574
4675 cx. tcx . sess . prof . generic_activity ( "build_primitive_trait_impls" ) . run ( || {
4776 for def_id in PrimitiveType :: all_impls ( cx. tcx ) {
4877 // Try to inline primitive impls from other crates.
4978 if !def_id. is_local ( ) {
50- inline:: build_impl ( cx, None , def_id, None , & mut new_items ) ;
79+ inline:: build_impl ( cx, None , def_id, None , & mut new_items_external ) ;
5180 }
5281 }
5382 for ( prim, did) in PrimitiveType :: primitive_locations ( cx. tcx ) {
@@ -57,7 +86,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
5786 if did. is_local ( ) {
5887 for def_id in prim. impls ( cx. tcx ) {
5988 let impls = get_auto_trait_and_blanket_impls ( cx, def_id) ;
60- new_items . extend ( impls. filter ( |i| cx. inlined . insert ( i. item_id ) ) ) ;
89+ new_items_external . extend ( impls. filter ( |i| cx. inlined . insert ( i. item_id ) ) ) ;
6190 }
6291 }
6392 }
@@ -71,6 +100,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
71100 cx : & DocContext < ' _ > ,
72101 map : & FxHashMap < DefId , & Type > ,
73102 cleaner : & mut BadImplStripper < ' _ > ,
103+ targets : & mut FxHashSet < DefId > ,
74104 type_did : DefId ,
75105 ) {
76106 if let Some ( target) = map. get ( & type_did) {
@@ -79,18 +109,18 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
79109 cleaner. prims . insert ( target_prim) ;
80110 } else if let Some ( target_did) = target. def_id ( & cx. cache ) {
81111 // `impl Deref<Target = S> for S`
82- if target_did == type_did {
112+ if !targets . insert ( target_did) {
83113 // Avoid infinite cycles
84114 return ;
85115 }
86116 cleaner. items . insert ( target_did. into ( ) ) ;
87- add_deref_target ( cx, map, cleaner, target_did) ;
117+ add_deref_target ( cx, map, cleaner, targets , target_did) ;
88118 }
89119 }
90120 }
91121
92122 // scan through included items ahead of time to splice in Deref targets to the "valid" sets
93- for it in & new_items {
123+ for it in new_items_external . iter ( ) . chain ( new_items_local . iter ( ) ) {
94124 if let ImplItem ( Impl { ref for_, ref trait_, ref items, .. } ) = * it. kind {
95125 if trait_. as_ref ( ) . map ( |t| t. def_id ( ) ) == cx. tcx . lang_items ( ) . deref_trait ( )
96126 && cleaner. keep_impl ( for_, true )
@@ -114,15 +144,24 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
114144 // `Deref` target type and the impl for type positions, this map of types is keyed by
115145 // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
116146 if cleaner. keep_impl_with_def_id ( for_did. into ( ) ) {
117- add_deref_target ( cx, & type_did_to_deref_target, & mut cleaner, for_did) ;
147+ let mut targets = FxHashSet :: default ( ) ;
148+ targets. insert ( for_did) ;
149+ add_deref_target (
150+ cx,
151+ & type_did_to_deref_target,
152+ & mut cleaner,
153+ & mut targets,
154+ for_did,
155+ ) ;
118156 }
119157 }
120158 }
121159 }
122160 }
123161 }
124162
125- new_items. retain ( |it| {
163+ // Filter out external items that are not needed
164+ new_items_external. retain ( |it| {
126165 if let ImplItem ( Impl { ref for_, ref trait_, ref kind, .. } ) = * it. kind {
127166 cleaner. keep_impl (
128167 for_,
@@ -134,37 +173,10 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
134173 }
135174 } ) ;
136175
137- // Local trait impls.
138- cx. with_all_trait_impls ( |cx, all_trait_impls| {
139- let _prof_timer = cx. tcx . sess . prof . generic_activity ( "build_local_trait_impls" ) ;
140- let mut attr_buf = Vec :: new ( ) ;
141- for & impl_def_id in all_trait_impls. iter ( ) . take_while ( |def_id| def_id. is_local ( ) ) {
142- let mut parent = cx. tcx . parent ( impl_def_id) ;
143- while let Some ( did) = parent {
144- attr_buf. extend (
145- cx. tcx
146- . get_attrs ( did)
147- . iter ( )
148- . filter ( |attr| attr. has_name ( sym:: doc) )
149- . filter ( |attr| {
150- if let Some ( [ attr] ) = attr. meta_item_list ( ) . as_deref ( ) {
151- attr. has_name ( sym:: cfg)
152- } else {
153- false
154- }
155- } )
156- . cloned ( ) ,
157- ) ;
158- parent = cx. tcx . parent ( did) ;
159- }
160- inline:: build_impl ( cx, None , impl_def_id, Some ( & attr_buf) , & mut new_items) ;
161- attr_buf. clear ( ) ;
162- }
163- } ) ;
164-
165176 if let ModuleItem ( Module { items, .. } ) = & mut * krate. module . kind {
166177 items. extend ( synth_impls) ;
167- items. extend ( new_items) ;
178+ items. extend ( new_items_external) ;
179+ items. extend ( new_items_local) ;
168180 } else {
169181 panic ! ( "collect-trait-impls can't run" ) ;
170182 } ;
0 commit comments