X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_query_system%2Fsrc%2Fquery%2Fplumbing.rs;h=848fa67e3df25f4e1643b9ca06a004747ae092a7;hb=947fe7e341c2c3c0bdb220fd31bb650ac24c7054;hp=f8d93a27d1c2bbbb3ceff184ae2702235eef9387;hpb=e69b84204aecf27fe18ada467f78c83b788b80e4;p=rust.git diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index f8d93a27d1c..848fa67e3df 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -3,6 +3,7 @@ //! manage the caches, and so forth. use crate::dep_graph::{DepContext, DepNode, DepNodeIndex, DepNodeParams}; +use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; use crate::query::config::QueryVTable; use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; @@ -19,6 +20,7 @@ use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; +use std::borrow::Borrow; use std::cell::Cell; use std::collections::hash_map::Entry; use std::fmt::Debug; @@ -369,11 +371,26 @@ fn try_execute_query( C: QueryCache, C::Key: Clone + DepNodeParams, C::Value: Value, + C::Stored: Debug + std::borrow::Borrow, Qcx: QueryContext, { match JobOwner::<'_, C::Key>::try_start(&qcx, state, span, key.clone()) { TryGetJob::NotYetStarted(job) => { - let (result, dep_node_index) = execute_job(qcx, key, dep_node, query, job.id); + let (result, dep_node_index) = execute_job(qcx, key.clone(), dep_node, query, job.id); + if query.feedable { + // We may have put a value inside the cache from inside the execution. + // Verify that it has the same hash as what we have now, to ensure consistency. + let _ = cache.lookup(&key, |cached_result, _| { + let hasher = query.hash_result.expect("feedable forbids no_hash"); + let old_hash = qcx.dep_context().with_stable_hashing_context(|mut hcx| hasher(&mut hcx, cached_result.borrow())); + let new_hash = qcx.dep_context().with_stable_hashing_context(|mut hcx| hasher(&mut hcx, &result)); + debug_assert_eq!( + old_hash, new_hash, + "Computed query value for {:?}({:?}) is inconsistent with fed value,\ncomputed={:#?}\nfed={:#?}", + query.dep_kind, key, result, cached_result, + ); + }); + } let result = job.complete(cache, result, dep_node_index); (result, Some(dep_node_index)) } @@ -525,7 +542,7 @@ fn try_load_from_disk_and_cache_in_memory( if std::intrinsics::unlikely( try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, ) { - incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query); + incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query.hash_result); } return Some((result, dep_node_index)); @@ -558,39 +575,42 @@ fn try_load_from_disk_and_cache_in_memory( // // See issue #82920 for an example of a miscompilation that would get turned into // an ICE by this check - incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query); + incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query.hash_result); Some((result, dep_node_index)) } -#[instrument(skip(qcx, result, query), level = "debug")] -fn incremental_verify_ich( - qcx: Qcx::DepContext, +#[instrument(skip(tcx, result, hash_result), level = "debug")] +pub(crate) fn incremental_verify_ich( + tcx: Tcx, result: &V, - dep_node: &DepNode, - query: &QueryVTable, -) where - Qcx: QueryContext, + dep_node: &DepNode, + hash_result: Option, &V) -> Fingerprint>, +) -> Fingerprint +where + Tcx: DepContext, { assert!( - qcx.dep_graph().is_green(dep_node), + tcx.dep_graph().is_green(dep_node), "fingerprint for green query instance not loaded from cache: {:?}", dep_node, ); - let new_hash = query.hash_result.map_or(Fingerprint::ZERO, |f| { - qcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) + let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { + tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) }); - let old_hash = qcx.dep_graph().prev_fingerprint_of(dep_node); + let old_hash = tcx.dep_graph().prev_fingerprint_of(dep_node); if Some(new_hash) != old_hash { incremental_verify_ich_failed( - qcx.sess(), + tcx.sess(), DebugArg::from(&dep_node), DebugArg::from(&result), ); } + + new_hash } // This DebugArg business is largely a mirror of std::fmt::ArgumentV1, which is