Skip to content

Commit 45c93e3

Browse files
Make iteration order of region_scope_tree query stable
1 parent a775f34 commit 45c93e3

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

compiler/rustc_middle/src/middle/region.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
88
99
use crate::ty::TyCtxt;
10-
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
11-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
10+
use rustc_data_structures::fx::FxIndexMap;
11+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
12+
use rustc_data_structures::unord::UnordMap;
1213
use rustc_hir as hir;
1314
use rustc_hir::{HirIdMap, Node};
1415
use rustc_macros::HashStable;
@@ -306,12 +307,12 @@ pub struct ScopeTree {
306307
/// The reason is that semantically, until the `box` expression returns,
307308
/// the values are still owned by their containing expressions. So
308309
/// we'll see that `&x`.
309-
pub yield_in_scope: FxHashMap<Scope, Vec<YieldData>>,
310+
pub yield_in_scope: UnordMap<Scope, Vec<YieldData>>,
310311

311312
/// The number of visit_expr and visit_pat calls done in the body.
312313
/// Used to sanity check visit_expr/visit_pat call count when
313314
/// calculating coroutine interiors.
314-
pub body_expr_count: FxHashMap<hir::BodyId, usize>,
315+
pub body_expr_count: UnordMap<hir::BodyId, usize>,
315316
}
316317

317318
/// Identifies the reason that a given expression is an rvalue candidate
@@ -430,11 +431,23 @@ impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
430431
} = *self;
431432

432433
root_body.hash_stable(hcx, hasher);
433-
body_expr_count.hash_stable(hcx, hasher);
434434
parent_map.hash_stable(hcx, hasher);
435435
var_map.hash_stable(hcx, hasher);
436436
destruction_scopes.hash_stable(hcx, hasher);
437437
rvalue_candidates.hash_stable(hcx, hasher);
438438
yield_in_scope.hash_stable(hcx, hasher);
439+
440+
// Hashing `body_expr_count` verbatim triggers an assertion that `BodyId`
441+
// should not be hashed outside of HIR hashing. We can only choose between
442+
// deeply hashing the HIR body behind the `BodyId` or not hashing the
443+
// `BodyId` at all. Neither is a good choice here, so we manually
444+
// transform to the stable hash key version and hash that. This
445+
// effectively hashes the `BodyId` as `(DefPathHash, ItemLocalId)`, i.e.
446+
// as an identifier.
447+
body_expr_count
448+
.items()
449+
.map(|(id, c)| (id.to_stable_hash_key(hcx), c))
450+
.into_sorted_stable_ord()
451+
.hash_stable(hcx, hasher);
439452
}
440453
}

compiler/rustc_span/src/def_id.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::{HashStableContext, Symbol};
22
use rustc_data_structures::fingerprint::Fingerprint;
3-
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey};
3+
use rustc_data_structures::stable_hasher::{
4+
Hash64, HashStable, StableHasher, StableOrd, ToStableHashKey,
5+
};
46
use rustc_data_structures::unhash::Unhasher;
57
use rustc_data_structures::AtomicRef;
68
use rustc_index::Idx;
@@ -134,6 +136,11 @@ impl Default for DefPathHash {
134136
}
135137
}
136138

139+
// Safety: `DefPathHash` sort order is not affected (de)serialization.
140+
unsafe impl StableOrd for DefPathHash {
141+
const CAN_USE_UNSTABLE_SORT: bool = true;
142+
}
143+
137144
/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
138145
/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
139146
/// [`DefId`]. It is stable across compilation sessions.
@@ -492,6 +499,15 @@ impl<CTX: HashStableContext> ToStableHashKey<CTX> for CrateNum {
492499
}
493500
}
494501

502+
impl<CTX: HashStableContext> ToStableHashKey<CTX> for DefPathHash {
503+
type KeyType = DefPathHash;
504+
505+
#[inline]
506+
fn to_stable_hash_key(&self, _: &CTX) -> DefPathHash {
507+
*self
508+
}
509+
}
510+
495511
macro_rules! typed_def_id {
496512
($Name:ident, $LocalName:ident) => {
497513
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]

0 commit comments

Comments
 (0)