@@ -193,7 +193,11 @@ impl Cache {
193193 }
194194
195195 cache. stack . push ( krate. name . to_string ( ) ) ;
196- krate = cache. fold_crate ( krate) ;
196+
197+ krate = {
198+ let mut cache_wrapper = CacheWrapper { cache : & mut cache, tmp_cache : Cache :: default ( ) } ;
199+ cache_wrapper. fold_crate ( krate)
200+ } ;
197201
198202 for ( trait_did, dids, impl_) in cache. orphan_trait_impls . drain ( ..) {
199203 if cache. traits . contains_key ( & trait_did) {
@@ -207,7 +211,15 @@ impl Cache {
207211 }
208212}
209213
210- impl DocFolder for Cache {
214+ /// This struct is needed because we need to use an empty `Cache` for all functions requiring
215+ /// a `Cache`. If we use the already filled one (`cache` in here), it'll provide information
216+ /// about implementations that aren't related to the type being checked.
217+ struct CacheWrapper < ' a > {
218+ cache : & ' a mut Cache ,
219+ tmp_cache : Cache ,
220+ }
221+
222+ impl < ' a > DocFolder for CacheWrapper < ' a > {
211223 fn fold_item ( & mut self , item : clean:: Item ) -> Option < clean:: Item > {
212224 if item. def_id . is_local ( ) {
213225 debug ! ( "folding {} \" {:?}\" , id {:?}" , item. type_( ) , item. name, item. def_id) ;
@@ -217,17 +229,21 @@ impl DocFolder for Cache {
217229 // we don't want it or its children in the search index.
218230 let orig_stripped_mod = match * item. kind {
219231 clean:: StrippedItem ( box clean:: ModuleItem ( ..) ) => {
220- mem:: replace ( & mut self . stripped_mod , true )
232+ mem:: replace ( & mut self . cache . stripped_mod , true )
221233 }
222- _ => self . stripped_mod ,
234+ _ => self . cache . stripped_mod ,
223235 } ;
224236
225237 // If the impl is from a masked crate or references something from a
226238 // masked crate then remove it completely.
227239 if let clean:: ImplItem ( ref i) = * item. kind {
228- if self . masked_crates . contains ( & item. def_id . krate )
229- || i. trait_ . def_id ( self ) . map_or ( false , |d| self . masked_crates . contains ( & d. krate ) )
230- || i. for_ . def_id ( self ) . map_or ( false , |d| self . masked_crates . contains ( & d. krate ) )
240+ if self . cache . masked_crates . contains ( & item. def_id . krate )
241+ || i. trait_
242+ . def_id ( & self . tmp_cache )
243+ . map_or ( false , |d| self . cache . masked_crates . contains ( & d. krate ) )
244+ || i. for_
245+ . def_id ( & self . tmp_cache )
246+ . map_or ( false , |d| self . cache . masked_crates . contains ( & d. krate ) )
231247 {
232248 return None ;
233249 }
@@ -236,14 +252,15 @@ impl DocFolder for Cache {
236252 // Propagate a trait method's documentation to all implementors of the
237253 // trait.
238254 if let clean:: TraitItem ( ref t) = * item. kind {
239- self . traits . entry ( item. def_id ) . or_insert_with ( || t. clone ( ) ) ;
255+ self . cache . traits . entry ( item. def_id ) . or_insert_with ( || t. clone ( ) ) ;
240256 }
241257
242258 // Collect all the implementors of traits.
243259 if let clean:: ImplItem ( ref i) = * item. kind {
244- if let Some ( did) = i. trait_ . def_id ( self ) {
260+ if let Some ( did) = i. trait_ . def_id ( & self . tmp_cache ) {
245261 if i. blanket_impl . is_none ( ) {
246- self . implementors
262+ self . cache
263+ . implementors
247264 . entry ( did)
248265 . or_default ( )
249266 . push ( Impl { impl_item : item. clone ( ) } ) ;
@@ -256,7 +273,7 @@ impl DocFolder for Cache {
256273 let ( parent, is_inherent_impl_item) = match * item. kind {
257274 clean:: StrippedItem ( ..) => ( ( None , None ) , false ) ,
258275 clean:: AssocConstItem ( ..) | clean:: TypedefItem ( _, true )
259- if self . parent_is_trait_impl =>
276+ if self . cache . parent_is_trait_impl =>
260277 {
261278 // skip associated items in trait impls
262279 ( ( None , None ) , false )
@@ -266,18 +283,18 @@ impl DocFolder for Cache {
266283 | clean:: StructFieldItem ( ..)
267284 | clean:: VariantItem ( ..) => (
268285 (
269- Some ( * self . parent_stack . last ( ) . expect ( "parent_stack is empty" ) ) ,
270- Some ( & self . stack [ ..self . stack . len ( ) - 1 ] ) ,
286+ Some ( * self . cache . parent_stack . last ( ) . expect ( "parent_stack is empty" ) ) ,
287+ Some ( & self . cache . stack [ ..self . cache . stack . len ( ) - 1 ] ) ,
271288 ) ,
272289 false ,
273290 ) ,
274291 clean:: MethodItem ( ..) | clean:: AssocConstItem ( ..) => {
275- if self . parent_stack . is_empty ( ) {
292+ if self . cache . parent_stack . is_empty ( ) {
276293 ( ( None , None ) , false )
277294 } else {
278- let last = self . parent_stack . last ( ) . expect ( "parent_stack is empty 2" ) ;
295+ let last = self . cache . parent_stack . last ( ) . expect ( "parent_stack is empty 2" ) ;
279296 let did = * last;
280- let path = match self . paths . get ( & did) {
297+ let path = match self . cache . paths . get ( & did) {
281298 // The current stack not necessarily has correlation
282299 // for where the type was defined. On the other
283300 // hand, `paths` always has the right
@@ -289,24 +306,24 @@ impl DocFolder for Cache {
289306 | ItemType :: Union
290307 | ItemType :: Enum ,
291308 ) ) => Some ( & fqp[ ..fqp. len ( ) - 1 ] ) ,
292- Some ( ..) => Some ( & * self . stack ) ,
309+ Some ( ..) => Some ( & * self . cache . stack ) ,
293310 None => None ,
294311 } ;
295312 ( ( Some ( * last) , path) , true )
296313 }
297314 }
298- _ => ( ( None , Some ( & * self . stack ) ) , false ) ,
315+ _ => ( ( None , Some ( & * self . cache . stack ) ) , false ) ,
299316 } ;
300317
301318 match parent {
302- ( parent, Some ( path) ) if is_inherent_impl_item || !self . stripped_mod => {
319+ ( parent, Some ( path) ) if is_inherent_impl_item || !self . cache . stripped_mod => {
303320 debug_assert ! ( !item. is_stripped( ) ) ;
304321
305322 // A crate has a module at its root, containing all items,
306323 // which should not be indexed. The crate-item itself is
307324 // inserted later on when serializing the search-index.
308325 if item. def_id . index != CRATE_DEF_INDEX {
309- self . search_index . push ( IndexItem {
326+ self . cache . search_index . push ( IndexItem {
310327 ty : item. type_ ( ) ,
311328 name : s. to_string ( ) ,
312329 path : path. join ( "::" ) ,
@@ -315,21 +332,22 @@ impl DocFolder for Cache {
315332 . map_or_else ( String :: new, |x| short_markdown_summary ( & x. as_str ( ) ) ) ,
316333 parent,
317334 parent_idx : None ,
318- search_type : get_index_search_type ( & item, self ) ,
335+ search_type : get_index_search_type ( & item, & self . tmp_cache ) ,
319336 } ) ;
320337
321338 for alias in item. attrs . get_doc_aliases ( ) {
322- self . aliases
339+ self . cache
340+ . aliases
323341 . entry ( alias. to_lowercase ( ) )
324342 . or_insert ( Vec :: new ( ) )
325- . push ( self . search_index . len ( ) - 1 ) ;
343+ . push ( self . cache . search_index . len ( ) - 1 ) ;
326344 }
327345 }
328346 }
329347 ( Some ( parent) , None ) if is_inherent_impl_item => {
330348 // We have a parent, but we don't know where they're
331349 // defined yet. Wait for later to index this item.
332- self . orphan_impl_items . push ( ( parent, item. clone ( ) ) ) ;
350+ self . cache . orphan_impl_items . push ( ( parent, item. clone ( ) ) ) ;
333351 }
334352 _ => { }
335353 }
@@ -338,7 +356,7 @@ impl DocFolder for Cache {
338356 // Keep track of the fully qualified path for this item.
339357 let pushed = match item. name {
340358 Some ( n) if !n. is_empty ( ) => {
341- self . stack . push ( n. to_string ( ) ) ;
359+ self . cache . stack . push ( n. to_string ( ) ) ;
342360 true
343361 }
344362 _ => false ,
@@ -360,54 +378,54 @@ impl DocFolder for Cache {
360378 | clean:: MacroItem ( ..)
361379 | clean:: ProcMacroItem ( ..)
362380 | clean:: VariantItem ( ..)
363- if !self . stripped_mod =>
381+ if !self . cache . stripped_mod =>
364382 {
365383 // Re-exported items mean that the same id can show up twice
366384 // in the rustdoc ast that we're looking at. We know,
367385 // however, that a re-exported item doesn't show up in the
368386 // `public_items` map, so we can skip inserting into the
369387 // paths map if there was already an entry present and we're
370388 // not a public item.
371- if !self . paths . contains_key ( & item. def_id )
372- || self . access_levels . is_public ( item. def_id )
389+ if !self . cache . paths . contains_key ( & item. def_id )
390+ || self . cache . access_levels . is_public ( item. def_id )
373391 {
374- self . paths . insert ( item. def_id , ( self . stack . clone ( ) , item. type_ ( ) ) ) ;
392+ self . cache . paths . insert ( item. def_id , ( self . cache . stack . clone ( ) , item. type_ ( ) ) ) ;
375393 }
376394 }
377395 clean:: PrimitiveItem ( ..) => {
378- self . paths . insert ( item. def_id , ( self . stack . clone ( ) , item. type_ ( ) ) ) ;
396+ self . cache . paths . insert ( item. def_id , ( self . cache . stack . clone ( ) , item. type_ ( ) ) ) ;
379397 }
380398
381399 _ => { }
382400 }
383401
384402 // Maintain the parent stack
385- let orig_parent_is_trait_impl = self . parent_is_trait_impl ;
403+ let orig_parent_is_trait_impl = self . cache . parent_is_trait_impl ;
386404 let parent_pushed = match * item. kind {
387405 clean:: TraitItem ( ..)
388406 | clean:: EnumItem ( ..)
389407 | clean:: ForeignTypeItem
390408 | clean:: StructItem ( ..)
391409 | clean:: UnionItem ( ..)
392410 | clean:: VariantItem ( ..) => {
393- self . parent_stack . push ( item. def_id ) ;
394- self . parent_is_trait_impl = false ;
411+ self . cache . parent_stack . push ( item. def_id ) ;
412+ self . cache . parent_is_trait_impl = false ;
395413 true
396414 }
397415 clean:: ImplItem ( ref i) => {
398- self . parent_is_trait_impl = i. trait_ . is_some ( ) ;
416+ self . cache . parent_is_trait_impl = i. trait_ . is_some ( ) ;
399417 match i. for_ {
400418 clean:: ResolvedPath { did, .. } => {
401- self . parent_stack . push ( did) ;
419+ self . cache . parent_stack . push ( did) ;
402420 true
403421 }
404422 ref t => {
405423 let prim_did = t
406424 . primitive_type ( )
407- . and_then ( |t| self . primitive_locations . get ( & t) . cloned ( ) ) ;
425+ . and_then ( |t| self . cache . primitive_locations . get ( & t) . cloned ( ) ) ;
408426 match prim_did {
409427 Some ( did) => {
410- self . parent_stack . push ( did) ;
428+ self . cache . parent_stack . push ( did) ;
411429 true
412430 }
413431 None => false ,
@@ -432,8 +450,9 @@ impl DocFolder for Cache {
432450 dids. insert ( did) ;
433451 }
434452 ref t => {
435- let did =
436- t. primitive_type ( ) . and_then ( |t| self . primitive_locations . get ( & t) . cloned ( ) ) ;
453+ let did = t
454+ . primitive_type ( )
455+ . and_then ( |t| self . cache . primitive_locations . get ( & t) . cloned ( ) ) ;
437456
438457 if let Some ( did) = did {
439458 dids. insert ( did) ;
@@ -443,33 +462,36 @@ impl DocFolder for Cache {
443462
444463 if let Some ( generics) = i. trait_ . as_ref ( ) . and_then ( |t| t. generics ( ) ) {
445464 for bound in generics {
446- if let Some ( did) = bound. def_id ( self ) {
465+ if let Some ( did) = bound. def_id ( & self . tmp_cache ) {
447466 dids. insert ( did) ;
448467 }
449468 }
450469 }
451470 let impl_item = Impl { impl_item : item } ;
452- if impl_item. trait_did ( self ) . map_or ( true , |d| self . traits . contains_key ( & d) ) {
471+ if impl_item
472+ . trait_did ( & self . tmp_cache )
473+ . map_or ( true , |d| self . cache . traits . contains_key ( & d) )
474+ {
453475 for did in dids {
454- self . impls . entry ( did) . or_insert ( vec ! [ ] ) . push ( impl_item. clone ( ) ) ;
476+ self . cache . impls . entry ( did) . or_insert ( vec ! [ ] ) . push ( impl_item. clone ( ) ) ;
455477 }
456478 } else {
457- let trait_did = impl_item. trait_did ( self ) . expect ( "no trait did" ) ;
458- self . orphan_trait_impls . push ( ( trait_did, dids, impl_item) ) ;
479+ let trait_did = impl_item. trait_did ( & self . tmp_cache ) . expect ( "no trait did" ) ;
480+ self . cache . orphan_trait_impls . push ( ( trait_did, dids, impl_item) ) ;
459481 }
460482 None
461483 } else {
462484 Some ( item)
463485 } ;
464486
465487 if pushed {
466- self . stack . pop ( ) . expect ( "stack already empty" ) ;
488+ self . cache . stack . pop ( ) . expect ( "stack already empty" ) ;
467489 }
468490 if parent_pushed {
469- self . parent_stack . pop ( ) . expect ( "parent stack already empty" ) ;
491+ self . cache . parent_stack . pop ( ) . expect ( "parent stack already empty" ) ;
470492 }
471- self . stripped_mod = orig_stripped_mod;
472- self . parent_is_trait_impl = orig_parent_is_trait_impl;
493+ self . cache . stripped_mod = orig_stripped_mod;
494+ self . cache . parent_is_trait_impl = orig_parent_is_trait_impl;
473495 ret
474496 }
475497}
0 commit comments