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:
commit
d63a8d965e
9 changed files with 120 additions and 48 deletions
|
@ -3,6 +3,7 @@ use rustc_ast as ast;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::stable_hasher::{HashingControls, NodeIdHashingMode};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
|
@ -26,20 +27,15 @@ fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
|
|||
pub struct StableHashingContext<'a> {
|
||||
definitions: &'a Definitions,
|
||||
cstore: &'a dyn CrateStore,
|
||||
// The value of `-Z incremental-ignore-spans`.
|
||||
// This field should only be used by `debug_opts_incremental_ignore_span`
|
||||
incremental_ignore_spans: bool,
|
||||
pub(super) body_resolver: BodyResolver<'a>,
|
||||
hash_spans: bool,
|
||||
pub(super) node_id_hashing_mode: NodeIdHashingMode,
|
||||
|
||||
// Very often, we are hashing something that does not need the
|
||||
// `CachingSourceMapView`, so we initialize it lazily.
|
||||
raw_source_map: &'a SourceMap,
|
||||
caching_source_map: Option<CachingSourceMapView<'a>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum NodeIdHashingMode {
|
||||
Ignore,
|
||||
HashDefPath,
|
||||
pub(super) hashing_controls: HashingControls,
|
||||
}
|
||||
|
||||
/// The `BodyResolver` allows mapping a `BodyId` to the corresponding `hir::Body`.
|
||||
|
@ -70,10 +66,13 @@ impl<'a> StableHashingContext<'a> {
|
|||
body_resolver: BodyResolver::Forbidden,
|
||||
definitions,
|
||||
cstore,
|
||||
incremental_ignore_spans: sess.opts.debugging_opts.incremental_ignore_spans,
|
||||
caching_source_map: None,
|
||||
raw_source_map: sess.source_map(),
|
||||
hash_spans: hash_spans_initial,
|
||||
node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
|
||||
hashing_controls: HashingControls {
|
||||
hash_spans: hash_spans_initial,
|
||||
node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,10 +132,10 @@ impl<'a> StableHashingContext<'a> {
|
|||
|
||||
#[inline]
|
||||
pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) {
|
||||
let prev_hash_spans = self.hash_spans;
|
||||
self.hash_spans = hash_spans;
|
||||
let prev_hash_spans = self.hashing_controls.hash_spans;
|
||||
self.hashing_controls.hash_spans = hash_spans;
|
||||
f(self);
|
||||
self.hash_spans = prev_hash_spans;
|
||||
self.hashing_controls.hash_spans = prev_hash_spans;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -145,10 +144,10 @@ impl<'a> StableHashingContext<'a> {
|
|||
mode: NodeIdHashingMode,
|
||||
f: F,
|
||||
) {
|
||||
let prev = self.node_id_hashing_mode;
|
||||
self.node_id_hashing_mode = mode;
|
||||
let prev = self.hashing_controls.node_id_hashing_mode;
|
||||
self.hashing_controls.node_id_hashing_mode = mode;
|
||||
f(self);
|
||||
self.node_id_hashing_mode = prev;
|
||||
self.hashing_controls.node_id_hashing_mode = prev;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -183,6 +182,11 @@ impl<'a> StableHashingContext<'a> {
|
|||
}
|
||||
IGNORED_ATTRIBUTES.with(|attrs| attrs.contains(&name))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hashing_controls(&self) -> HashingControls {
|
||||
self.hashing_controls.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
|
||||
|
@ -195,7 +199,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
|
|||
impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
||||
#[inline]
|
||||
fn hash_spans(&self) -> bool {
|
||||
self.hash_spans
|
||||
self.hashing_controls.hash_spans
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn debug_opts_incremental_ignore_spans(&self) -> bool {
|
||||
self.incremental_ignore_spans
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -215,6 +224,11 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
|||
) -> Option<(Lrc<SourceFile>, usize, BytePos, usize, BytePos)> {
|
||||
self.source_map().span_data_to_lines_and_cols(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hashing_controls(&self) -> HashingControls {
|
||||
self.hashing_controls.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
|
|||
#[inline]
|
||||
fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
|
||||
let hcx = self;
|
||||
match hcx.node_id_hashing_mode {
|
||||
match hcx.hashing_controls.node_id_hashing_mode {
|
||||
NodeIdHashingMode::Ignore => {
|
||||
// Don't do anything.
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
|
|||
|
||||
#[inline]
|
||||
fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
|
||||
let prev_hash_node_ids = self.node_id_hashing_mode;
|
||||
self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
|
||||
let prev_hash_node_ids = self.hashing_controls.node_id_hashing_mode;
|
||||
self.hashing_controls.node_id_hashing_mode = NodeIdHashingMode::Ignore;
|
||||
|
||||
f(self);
|
||||
|
||||
self.node_id_hashing_mode = prev_hash_node_ids;
|
||||
self.hashing_controls.node_id_hashing_mode = prev_hash_node_ids;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! ICH - Incremental Compilation Hash
|
||||
|
||||
pub use self::hcx::{NodeIdHashingMode, StableHashingContext};
|
||||
pub use self::hcx::StableHashingContext;
|
||||
pub use rustc_data_structures::stable_hasher::NodeIdHashingMode;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
mod hcx;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue