|
7 | 7 | //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
|
8 | 8 |
|
9 | 9 | 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; |
12 | 13 | use rustc_hir as hir;
|
13 | 14 | use rustc_hir::{HirIdMap, Node};
|
14 | 15 | use rustc_macros::HashStable;
|
@@ -306,12 +307,12 @@ pub struct ScopeTree {
|
306 | 307 | /// The reason is that semantically, until the `box` expression returns,
|
307 | 308 | /// the values are still owned by their containing expressions. So
|
308 | 309 | /// we'll see that `&x`.
|
309 |
| - pub yield_in_scope: FxHashMap<Scope, Vec<YieldData>>, |
| 310 | + pub yield_in_scope: UnordMap<Scope, Vec<YieldData>>, |
310 | 311 |
|
311 | 312 | /// The number of visit_expr and visit_pat calls done in the body.
|
312 | 313 | /// Used to sanity check visit_expr/visit_pat call count when
|
313 | 314 | /// calculating coroutine interiors.
|
314 |
| - pub body_expr_count: FxHashMap<hir::BodyId, usize>, |
| 315 | + pub body_expr_count: UnordMap<hir::BodyId, usize>, |
315 | 316 | }
|
316 | 317 |
|
317 | 318 | /// Identifies the reason that a given expression is an rvalue candidate
|
@@ -430,11 +431,23 @@ impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
|
430 | 431 | } = *self;
|
431 | 432 |
|
432 | 433 | root_body.hash_stable(hcx, hasher);
|
433 |
| - body_expr_count.hash_stable(hcx, hasher); |
434 | 434 | parent_map.hash_stable(hcx, hasher);
|
435 | 435 | var_map.hash_stable(hcx, hasher);
|
436 | 436 | destruction_scopes.hash_stable(hcx, hasher);
|
437 | 437 | rvalue_candidates.hash_stable(hcx, hasher);
|
438 | 438 | 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); |
439 | 452 | }
|
440 | 453 | }
|
0 commit comments