@@ -193,7 +193,11 @@ impl Cache {
193
193
}
194
194
195
195
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
+ } ;
197
201
198
202
for ( trait_did, dids, impl_) in cache. orphan_trait_impls . drain ( ..) {
199
203
if cache. traits . contains_key ( & trait_did) {
@@ -207,7 +211,15 @@ impl Cache {
207
211
}
208
212
}
209
213
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 > {
211
223
fn fold_item ( & mut self , item : clean:: Item ) -> Option < clean:: Item > {
212
224
if item. def_id . is_local ( ) {
213
225
debug ! ( "folding {} \" {:?}\" , id {:?}" , item. type_( ) , item. name, item. def_id) ;
@@ -217,17 +229,21 @@ impl DocFolder for Cache {
217
229
// we don't want it or its children in the search index.
218
230
let orig_stripped_mod = match * item. kind {
219
231
clean:: StrippedItem ( box clean:: ModuleItem ( ..) ) => {
220
- mem:: replace ( & mut self . stripped_mod , true )
232
+ mem:: replace ( & mut self . cache . stripped_mod , true )
221
233
}
222
- _ => self . stripped_mod ,
234
+ _ => self . cache . stripped_mod ,
223
235
} ;
224
236
225
237
// If the impl is from a masked crate or references something from a
226
238
// masked crate then remove it completely.
227
239
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 ) )
231
247
{
232
248
return None ;
233
249
}
@@ -236,14 +252,15 @@ impl DocFolder for Cache {
236
252
// Propagate a trait method's documentation to all implementors of the
237
253
// trait.
238
254
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 ( ) ) ;
240
256
}
241
257
242
258
// Collect all the implementors of traits.
243
259
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 ) {
245
261
if i. blanket_impl . is_none ( ) {
246
- self . implementors
262
+ self . cache
263
+ . implementors
247
264
. entry ( did)
248
265
. or_default ( )
249
266
. push ( Impl { impl_item : item. clone ( ) } ) ;
@@ -256,7 +273,7 @@ impl DocFolder for Cache {
256
273
let ( parent, is_inherent_impl_item) = match * item. kind {
257
274
clean:: StrippedItem ( ..) => ( ( None , None ) , false ) ,
258
275
clean:: AssocConstItem ( ..) | clean:: TypedefItem ( _, true )
259
- if self . parent_is_trait_impl =>
276
+ if self . cache . parent_is_trait_impl =>
260
277
{
261
278
// skip associated items in trait impls
262
279
( ( None , None ) , false )
@@ -266,18 +283,18 @@ impl DocFolder for Cache {
266
283
| clean:: StructFieldItem ( ..)
267
284
| clean:: VariantItem ( ..) => (
268
285
(
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 ] ) ,
271
288
) ,
272
289
false ,
273
290
) ,
274
291
clean:: MethodItem ( ..) | clean:: AssocConstItem ( ..) => {
275
- if self . parent_stack . is_empty ( ) {
292
+ if self . cache . parent_stack . is_empty ( ) {
276
293
( ( None , None ) , false )
277
294
} 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" ) ;
279
296
let did = * last;
280
- let path = match self . paths . get ( & did) {
297
+ let path = match self . cache . paths . get ( & did) {
281
298
// The current stack not necessarily has correlation
282
299
// for where the type was defined. On the other
283
300
// hand, `paths` always has the right
@@ -289,24 +306,24 @@ impl DocFolder for Cache {
289
306
| ItemType :: Union
290
307
| ItemType :: Enum ,
291
308
) ) => Some ( & fqp[ ..fqp. len ( ) - 1 ] ) ,
292
- Some ( ..) => Some ( & * self . stack ) ,
309
+ Some ( ..) => Some ( & * self . cache . stack ) ,
293
310
None => None ,
294
311
} ;
295
312
( ( Some ( * last) , path) , true )
296
313
}
297
314
}
298
- _ => ( ( None , Some ( & * self . stack ) ) , false ) ,
315
+ _ => ( ( None , Some ( & * self . cache . stack ) ) , false ) ,
299
316
} ;
300
317
301
318
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 => {
303
320
debug_assert ! ( !item. is_stripped( ) ) ;
304
321
305
322
// A crate has a module at its root, containing all items,
306
323
// which should not be indexed. The crate-item itself is
307
324
// inserted later on when serializing the search-index.
308
325
if item. def_id . index != CRATE_DEF_INDEX {
309
- self . search_index . push ( IndexItem {
326
+ self . cache . search_index . push ( IndexItem {
310
327
ty : item. type_ ( ) ,
311
328
name : s. to_string ( ) ,
312
329
path : path. join ( "::" ) ,
@@ -315,21 +332,22 @@ impl DocFolder for Cache {
315
332
. map_or_else ( String :: new, |x| short_markdown_summary ( & x. as_str ( ) ) ) ,
316
333
parent,
317
334
parent_idx : None ,
318
- search_type : get_index_search_type ( & item, self ) ,
335
+ search_type : get_index_search_type ( & item, & self . tmp_cache ) ,
319
336
} ) ;
320
337
321
338
for alias in item. attrs . get_doc_aliases ( ) {
322
- self . aliases
339
+ self . cache
340
+ . aliases
323
341
. entry ( alias. to_lowercase ( ) )
324
342
. or_insert ( Vec :: new ( ) )
325
- . push ( self . search_index . len ( ) - 1 ) ;
343
+ . push ( self . cache . search_index . len ( ) - 1 ) ;
326
344
}
327
345
}
328
346
}
329
347
( Some ( parent) , None ) if is_inherent_impl_item => {
330
348
// We have a parent, but we don't know where they're
331
349
// 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 ( ) ) ) ;
333
351
}
334
352
_ => { }
335
353
}
@@ -338,7 +356,7 @@ impl DocFolder for Cache {
338
356
// Keep track of the fully qualified path for this item.
339
357
let pushed = match item. name {
340
358
Some ( n) if !n. is_empty ( ) => {
341
- self . stack . push ( n. to_string ( ) ) ;
359
+ self . cache . stack . push ( n. to_string ( ) ) ;
342
360
true
343
361
}
344
362
_ => false ,
@@ -360,54 +378,54 @@ impl DocFolder for Cache {
360
378
| clean:: MacroItem ( ..)
361
379
| clean:: ProcMacroItem ( ..)
362
380
| clean:: VariantItem ( ..)
363
- if !self . stripped_mod =>
381
+ if !self . cache . stripped_mod =>
364
382
{
365
383
// Re-exported items mean that the same id can show up twice
366
384
// in the rustdoc ast that we're looking at. We know,
367
385
// however, that a re-exported item doesn't show up in the
368
386
// `public_items` map, so we can skip inserting into the
369
387
// paths map if there was already an entry present and we're
370
388
// 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 )
373
391
{
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_ ( ) ) ) ;
375
393
}
376
394
}
377
395
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_ ( ) ) ) ;
379
397
}
380
398
381
399
_ => { }
382
400
}
383
401
384
402
// 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 ;
386
404
let parent_pushed = match * item. kind {
387
405
clean:: TraitItem ( ..)
388
406
| clean:: EnumItem ( ..)
389
407
| clean:: ForeignTypeItem
390
408
| clean:: StructItem ( ..)
391
409
| clean:: UnionItem ( ..)
392
410
| 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 ;
395
413
true
396
414
}
397
415
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 ( ) ;
399
417
match i. for_ {
400
418
clean:: ResolvedPath { did, .. } => {
401
- self . parent_stack . push ( did) ;
419
+ self . cache . parent_stack . push ( did) ;
402
420
true
403
421
}
404
422
ref t => {
405
423
let prim_did = t
406
424
. primitive_type ( )
407
- . and_then ( |t| self . primitive_locations . get ( & t) . cloned ( ) ) ;
425
+ . and_then ( |t| self . cache . primitive_locations . get ( & t) . cloned ( ) ) ;
408
426
match prim_did {
409
427
Some ( did) => {
410
- self . parent_stack . push ( did) ;
428
+ self . cache . parent_stack . push ( did) ;
411
429
true
412
430
}
413
431
None => false ,
@@ -432,8 +450,9 @@ impl DocFolder for Cache {
432
450
dids. insert ( did) ;
433
451
}
434
452
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 ( ) ) ;
437
456
438
457
if let Some ( did) = did {
439
458
dids. insert ( did) ;
@@ -443,33 +462,36 @@ impl DocFolder for Cache {
443
462
444
463
if let Some ( generics) = i. trait_ . as_ref ( ) . and_then ( |t| t. generics ( ) ) {
445
464
for bound in generics {
446
- if let Some ( did) = bound. def_id ( self ) {
465
+ if let Some ( did) = bound. def_id ( & self . tmp_cache ) {
447
466
dids. insert ( did) ;
448
467
}
449
468
}
450
469
}
451
470
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
+ {
453
475
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 ( ) ) ;
455
477
}
456
478
} 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) ) ;
459
481
}
460
482
None
461
483
} else {
462
484
Some ( item)
463
485
} ;
464
486
465
487
if pushed {
466
- self . stack . pop ( ) . expect ( "stack already empty" ) ;
488
+ self . cache . stack . pop ( ) . expect ( "stack already empty" ) ;
467
489
}
468
490
if parent_pushed {
469
- self . parent_stack . pop ( ) . expect ( "parent stack already empty" ) ;
491
+ self . cache . parent_stack . pop ( ) . expect ( "parent stack already empty" ) ;
470
492
}
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;
473
495
ret
474
496
}
475
497
}
0 commit comments