@@ -133,8 +133,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
133
133
generator_kind => { cdata. generator_kind( def_id. index) }
134
134
opt_def_kind => { Some ( cdata. def_kind( def_id. index) ) }
135
135
def_span => { cdata. get_span( def_id. index, & tcx. sess) }
136
- def_ident_span => {
137
- cdata. try_item_ident( def_id. index, & tcx. sess) . ok( ) . map ( |ident| ident . span )
136
+ def_ident => {
137
+ cdata. try_item_ident( def_id. index, & tcx. sess) . ok( )
138
138
}
139
139
lookup_stability => {
140
140
cdata. get_stability( def_id. index) . map( |s| tcx. intern_stability( s) )
@@ -290,15 +290,11 @@ pub fn provide(providers: &mut Providers) {
290
290
// external item that is visible from at least one local module) to a
291
291
// sufficiently visible parent (considering modules that re-export the
292
292
// external item to be parents).
293
- visible_parent_map : |tcx, ( ) | {
294
- use std :: collections :: hash_map :: Entry ;
295
- use std:: collections:: vec_deque :: VecDeque ;
293
+ visible_parents_map : |tcx, ( ) | {
294
+ use rustc_data_structures :: fx :: FxHashSet ;
295
+ use std:: collections:: VecDeque ;
296
296
297
- let mut visible_parent_map: DefIdMap < DefId > = Default :: default ( ) ;
298
- // This is a secondary visible_parent_map, storing the DefId of parents that re-export
299
- // the child as `_`. Since we prefer parents that don't do this, merge this map at the
300
- // end, only if we're missing any keys from the former.
301
- let mut fallback_map: DefIdMap < DefId > = Default :: default ( ) ;
297
+ let mut visible_parents_map: DefIdMap < SmallVec < [ DefId ; 4 ] > > = DefIdMap :: default ( ) ;
302
298
303
299
// Issue 46112: We want the map to prefer the shortest
304
300
// paths when reporting the path to an item. Therefore we
@@ -310,59 +306,81 @@ pub fn provide(providers: &mut Providers) {
310
306
// only get paths that are locally minimal with respect to
311
307
// whatever crate we happened to encounter first in this
312
308
// traversal, but not globally minimal across all crates.
313
- let bfs_queue = & mut VecDeque :: new ( ) ;
314
-
315
- for & cnum in tcx. crates ( ( ) ) {
316
- // Ignore crates without a corresponding local `extern crate` item.
317
- if tcx. missing_extern_crate_item ( cnum) {
318
- continue ;
309
+ let mut bfs_queue = VecDeque :: default ( ) ;
310
+
311
+ bfs_queue. extend (
312
+ tcx. crates ( ( ) )
313
+ . into_iter ( )
314
+ // Ignore crates without a corresponding local `extern crate` item.
315
+ . filter ( |cnum| !tcx. missing_extern_crate_item ( * * cnum) )
316
+ . map ( |cnum| DefId { krate : * cnum, index : CRATE_DEF_INDEX } ) ,
317
+ ) ;
318
+
319
+ // Iterate over graph using BFS.
320
+ // Filter out any non-public items.
321
+ while let Some ( parent) = bfs_queue. pop_front ( ) {
322
+ for child in tcx
323
+ . item_children ( parent)
324
+ . iter ( )
325
+ . filter ( |child| child. vis . is_public ( ) )
326
+ . filter_map ( |child| child. res . opt_def_id ( ) )
327
+ {
328
+ visible_parents_map
329
+ . entry ( child)
330
+ . or_insert_with ( || {
331
+ // If we encounter node the first time
332
+ // add it to queue for next iterations
333
+ bfs_queue. push_back ( child) ;
334
+ Default :: default ( )
335
+ } )
336
+ . push ( parent) ;
319
337
}
338
+ }
320
339
321
- bfs_queue. push_back ( DefId { krate : cnum, index : CRATE_DEF_INDEX } ) ;
340
+ // Iterate over parents vector to remove duplicate elements
341
+ // while preserving order
342
+ let mut dedup_set = FxHashSet :: default ( ) ;
343
+ for ( _, parents) in & mut visible_parents_map {
344
+ parents. retain ( |parent| dedup_set. insert ( * parent) ) ;
345
+
346
+ // Reuse hashset allocation.
347
+ dedup_set. clear ( ) ;
322
348
}
323
349
324
- let mut add_child = |bfs_queue : & mut VecDeque < _ > , export : & Export , parent : DefId | {
325
- if !export. vis . is_public ( ) {
326
- return ;
327
- }
350
+ visible_parents_map
351
+ } ,
352
+ best_visible_parent : |tcx, child| {
353
+ // Use `min_by_key` because it returns
354
+ // first match in case keys are equal
355
+ tcx. visible_parents_map ( ( ) )
356
+ . get ( & child) ?
357
+ . into_iter ( )
358
+ . min_by_key ( |parent| {
359
+ // If this is just regular export in another module, assign it a neutral score.
360
+ let mut score = 0 ;
361
+
362
+ // If child and parent are local, we prefer them
363
+ if child. is_local ( ) && parent. is_local ( ) {
364
+ score += 1 ;
365
+ }
328
366
329
- if let Some ( child) = export . res . opt_def_id ( ) {
330
- if export . ident . name == kw :: Underscore {
331
- fallback_map . insert ( child , parent) ;
332
- return ;
367
+ // Even if child and parent are local, if parent is `#[doc(hidden)]`
368
+ // We reduce their score to avoid showing items not popping in documentation.
369
+ if ast :: attr :: is_doc_hidden ( tcx . item_attrs ( * * parent) ) {
370
+ score -= 2 ;
333
371
}
334
372
335
- match visible_parent_map. entry ( child) {
336
- Entry :: Occupied ( mut entry) => {
337
- // If `child` is defined in crate `cnum`, ensure
338
- // that it is mapped to a parent in `cnum`.
339
- if child. is_local ( ) && entry. get ( ) . is_local ( ) {
340
- entry. insert ( parent) ;
341
- }
342
- }
343
- Entry :: Vacant ( entry) => {
344
- entry. insert ( parent) ;
345
- bfs_queue. push_back ( child) ;
373
+ // If parent identifier is _ we prefer it only as last resort if other items are not available
374
+ if let Some ( ident) = tcx. def_ident ( * * parent) {
375
+ if ident. name == kw:: Underscore {
376
+ score -= 3 ;
346
377
}
347
378
}
348
- }
349
- } ;
350
-
351
- while let Some ( def) = bfs_queue. pop_front ( ) {
352
- for child in tcx. item_children ( def) . iter ( ) {
353
- add_child ( bfs_queue, child, def) ;
354
- }
355
- }
356
379
357
- // Fill in any missing entries with the (less preferable) path ending in `::_`.
358
- // We still use this path in a diagnostic that suggests importing `::*`.
359
- for ( child, parent) in fallback_map {
360
- visible_parent_map. entry ( child) . or_insert ( parent) ;
361
- }
362
-
363
- visible_parent_map
380
+ -score
381
+ } )
382
+ . map ( ToOwned :: to_owned)
364
383
} ,
365
-
366
384
dependency_formats : |tcx, ( ) | Lrc :: new ( crate :: dependency_format:: calculate ( tcx) ) ,
367
385
has_global_allocator : |tcx, cnum| {
368
386
assert_eq ! ( cnum, LOCAL_CRATE ) ;
0 commit comments