@@ -294,13 +294,31 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
294
294
assert_eq ! ( cnum, LOCAL_CRATE ) ;
295
295
let mut visible_parent_map: DefIdMap < DefId > = DefIdMap ( ) ;
296
296
297
+ // Issue 46112: We want the map to prefer the shortest
298
+ // paths when reporting the path to an item. Therefore we
299
+ // build up the map via a breadth-first search (BFS),
300
+ // which naturally yields minimal-length paths.
301
+ //
302
+ // Note that it needs to be a BFS over the whole forest of
303
+ // crates, not just each individual crate; otherwise you
304
+ // only get paths that are locally minimal with respect to
305
+ // whatever crate we happened to encounter first in this
306
+ // traversal, but not globally minimal across all crates.
307
+ let bfs_queue = & mut VecDeque :: new ( ) ;
297
308
for & cnum in tcx. crates ( ) . iter ( ) {
298
309
// Ignore crates without a corresponding local `extern crate` item.
299
310
if tcx. missing_extern_crate_item ( cnum) {
300
311
continue
301
312
}
302
313
303
- let bfs_queue = & mut VecDeque :: new ( ) ;
314
+ bfs_queue. push_back ( DefId {
315
+ krate : cnum,
316
+ index : CRATE_DEF_INDEX
317
+ } ) ;
318
+ }
319
+
320
+ // (restrict scope of mutable-borrow of `visible_parent_map`)
321
+ {
304
322
let visible_parent_map = & mut visible_parent_map;
305
323
let mut add_child = |bfs_queue : & mut VecDeque < _ > ,
306
324
child : & def:: Export ,
@@ -326,10 +344,6 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
326
344
}
327
345
} ;
328
346
329
- bfs_queue. push_back ( DefId {
330
- krate : cnum,
331
- index : CRATE_DEF_INDEX
332
- } ) ;
333
347
while let Some ( def) = bfs_queue. pop_front ( ) {
334
348
for child in tcx. item_children ( def) . iter ( ) {
335
349
add_child ( bfs_queue, child, def) ;
0 commit comments