Skip to content

Commit edebf77

Browse files
committed
Auto merge of rust-lang#89408 - Mark-Simulacrum:fix-query-nondet, r=petrochenkov
Avoid nondeterminism in trimmed_def_paths Previously this query depended on the global interning order of Symbols, which meant that irrelevant changes could influence the query and cause recompilations. This commit ensures that the return set is stable and will not be affected by the global order by deterministically (in lexicographic order) choosing a name to use if there are multiple names for a single DefId. This should fix the cause of the [regressions] in rust-lang#83343. [regressions]: https://perf.rust-lang.org/compare.html?start=9620f3a84b079decfdc2e557be007580b097fe43&end=addb4da686a97da46159f0123cb6cdc2ce3d7fdb
2 parents b27661e + 56fcf07 commit edebf77

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -2408,7 +2408,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
24082408
///
24092409
/// The implementation uses similar import discovery logic to that of 'use' suggestions.
24102410
fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
2411-
let mut map = FxHashMap::default();
2411+
let mut map: FxHashMap<DefId, Symbol> = FxHashMap::default();
24122412

24132413
if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths {
24142414
// 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> {
24462446
});
24472447

24482448
for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() {
2449+
use std::collections::hash_map::Entry::{Occupied, Vacant};
2450+
24492451
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+
}
24512472
}
24522473
}
24532474

0 commit comments

Comments
 (0)