Auto merge of #92278 - Aaron1011:fix-fingerprint-caching, r=michaelwoerister
Ensure that `Fingerprint` caching respects hashing configuration Fixes #92266 In some `HashStable` impls, we use a cache to avoid re-computing the same `Fingerprint` from the same structure (e.g. an `AdtDef`). However, the `StableHashingContext` used can be configured to perform hashing in different ways (e.g. skipping `Span`s). This configuration information is not included in the cache key, which will cause an incorrect `Fingerprint` to be used if we hash the same structure with different `StableHashingContext` settings. To fix this, the configuration settings of `StableHashingContext` are split out into a separate `HashingControls` struct. This struct is used as part of the cache key, ensuring that our caches always produce the correct result for the given settings. With this in place, we now turn off `Span` hashing during the entire process of computing the hash included in legacy symbols. This current has no effect, but will matter when a future PR starts hashing more `Span`s that we currently skip.
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::HashingControls;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir as hir;
|
||||
@@ -136,12 +137,13 @@ impl Hash for AdtDef {
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
thread_local! {
|
||||
static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = Default::default();
|
||||
static CACHE: RefCell<FxHashMap<(usize, HashingControls), Fingerprint>> = Default::default();
|
||||
}
|
||||
|
||||
let hash: Fingerprint = CACHE.with(|cache| {
|
||||
let addr = self as *const AdtDef as usize;
|
||||
*cache.borrow_mut().entry(addr).or_insert_with(|| {
|
||||
let hashing_controls = hcx.hashing_controls();
|
||||
*cache.borrow_mut().entry((addr, hashing_controls)).or_insert_with(|| {
|
||||
let ty::AdtDef { did, ref variants, ref flags, ref repr } = *self;
|
||||
|
||||
let mut hasher = StableHasher::new();
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::mir;
|
||||
use crate::ty;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::HashingControls;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use std::cell::RefCell;
|
||||
@@ -17,12 +18,12 @@ where
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
thread_local! {
|
||||
static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
|
||||
static CACHE: RefCell<FxHashMap<(usize, usize, HashingControls), Fingerprint>> =
|
||||
RefCell::new(Default::default());
|
||||
}
|
||||
|
||||
let hash = CACHE.with(|cache| {
|
||||
let key = (self.as_ptr() as usize, self.len());
|
||||
let key = (self.as_ptr() as usize, self.len(), hcx.hashing_controls());
|
||||
if let Some(&hash) = cache.borrow().get(&key) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user