@@ -2408,7 +2408,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
2408
2408
///
2409
2409
/// The implementation uses similar import discovery logic to that of 'use' suggestions.
2410
2410
fn trimmed_def_paths ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> FxHashMap < DefId , Symbol > {
2411
- let mut map = FxHashMap :: default ( ) ;
2411
+ let mut map: FxHashMap < DefId , Symbol > = FxHashMap :: default ( ) ;
2412
2412
2413
2413
if let TrimmedDefPaths :: GoodPath = tcx. sess . opts . trimmed_def_paths {
2414
2414
// For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths`
@@ -2446,8 +2446,29 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
2446
2446
} ) ;
2447
2447
2448
2448
for ( ( _, symbol) , opt_def_id) in unique_symbols_rev. drain ( ) {
2449
+ use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
2450
+
2449
2451
if let Some ( def_id) = opt_def_id {
2450
- map. insert ( def_id, symbol) ;
2452
+ match map. entry ( def_id) {
2453
+ Occupied ( mut v) => {
2454
+ // A single DefId can be known under multiple names (e.g.,
2455
+ // with a `pub use ... as ...;`). We need to ensure that the
2456
+ // name placed in this map is chosen deterministically, so
2457
+ // if we find multiple names (`symbol`) resolving to the
2458
+ // same `def_id`, we prefer the lexicographically smallest
2459
+ // name.
2460
+ //
2461
+ // Any stable ordering would be fine here though.
2462
+ if * v. get ( ) != symbol {
2463
+ if v. get ( ) . as_str ( ) > symbol. as_str ( ) {
2464
+ v. insert ( symbol) ;
2465
+ }
2466
+ }
2467
+ }
2468
+ Vacant ( v) => {
2469
+ v. insert ( symbol) ;
2470
+ }
2471
+ }
2451
2472
}
2452
2473
}
2453
2474
0 commit comments