Skip to content

Commit 9f2c6b0

Browse files
committed
Sanity check computed value for feeable queries.
1 parent ee7a9a8 commit 9f2c6b0

File tree

4 files changed

+42
-3
lines changed

4 files changed

+42
-3
lines changed

compiler/rustc_macros/src/query.rs

+9
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,15 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
359359
});
360360

361361
if modifiers.feedable.is_some() {
362+
assert!(modifiers.anon.is_none(), "Query {name} cannot be both `feedable` and `anon`.");
363+
assert!(
364+
modifiers.eval_always.is_none(),
365+
"Query {name} cannot be both `feedable` and `eval_always`."
366+
);
367+
assert!(
368+
modifiers.no_hash.is_none(),
369+
"Query {name} cannot be both `feedable` and `no_hash`."
370+
);
362371
feedable_queries.extend(quote! {
363372
#(#doc_comments)*
364373
[#attribute_stream] fn #name(#arg) #result,

compiler/rustc_query_impl/src/plumbing.rs

+13
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,18 @@ macro_rules! depth_limit {
252252
};
253253
}
254254

255+
macro_rules! feedable {
256+
([]) => {{
257+
false
258+
}};
259+
([(feedable) $($rest:tt)*]) => {{
260+
true
261+
}};
262+
([$other:tt $($modifiers:tt)*]) => {
263+
feedable!([$($modifiers)*])
264+
};
265+
}
266+
255267
macro_rules! hash_result {
256268
([]) => {{
257269
Some(dep_graph::hash_result)
@@ -491,6 +503,7 @@ macro_rules! define_queries {
491503
anon: is_anon!([$($modifiers)*]),
492504
eval_always: is_eval_always!([$($modifiers)*]),
493505
depth_limit: depth_limit!([$($modifiers)*]),
506+
feedable: feedable!([$($modifiers)*]),
494507
dep_kind: dep_graph::DepKind::$name,
495508
hash_result: hash_result!([$($modifiers)*]),
496509
handle_cycle_error: handle_cycle_error!([$($modifiers)*]),

compiler/rustc_query_system/src/query/config.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ pub trait QueryConfig<Qcx: QueryContext> {
1515
const NAME: &'static str;
1616

1717
type Key: Eq + Hash + Clone + Debug;
18-
type Value;
19-
type Stored: Clone;
18+
type Value: Debug;
19+
type Stored: Debug + Clone + std::borrow::Borrow<Self::Value>;
2020

2121
type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>;
2222

@@ -45,6 +45,7 @@ pub struct QueryVTable<Qcx: QueryContext, K, V> {
4545
pub dep_kind: Qcx::DepKind,
4646
pub eval_always: bool,
4747
pub depth_limit: bool,
48+
pub feedable: bool,
4849

4950
pub compute: fn(Qcx::DepContext, K) -> V,
5051
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,

compiler/rustc_query_system/src/query/plumbing.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_data_structures::sync::Lock;
2020
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
2121
use rustc_session::Session;
2222
use rustc_span::{Span, DUMMY_SP};
23+
use std::borrow::Borrow;
2324
use std::cell::Cell;
2425
use std::collections::hash_map::Entry;
2526
use std::fmt::Debug;
@@ -370,11 +371,26 @@ where
370371
C: QueryCache,
371372
C::Key: Clone + DepNodeParams<Qcx::DepContext>,
372373
C::Value: Value<Qcx::DepContext>,
374+
C::Stored: Debug + std::borrow::Borrow<C::Value>,
373375
Qcx: QueryContext,
374376
{
375377
match JobOwner::<'_, C::Key>::try_start(&qcx, state, span, key.clone()) {
376378
TryGetJob::NotYetStarted(job) => {
377-
let (result, dep_node_index) = execute_job(qcx, key, dep_node, query, job.id);
379+
let (result, dep_node_index) = execute_job(qcx, key.clone(), dep_node, query, job.id);
380+
if query.feedable {
381+
// We may have put a value inside the cache from inside the execution.
382+
// Verify that it has the same hash as what we have now, to ensure consistency.
383+
let _ = cache.lookup(&key, |cached_result, _| {
384+
let hasher = query.hash_result.expect("feedable forbids no_hash");
385+
let old_hash = qcx.dep_context().with_stable_hashing_context(|mut hcx| hasher(&mut hcx, cached_result.borrow()));
386+
let new_hash = qcx.dep_context().with_stable_hashing_context(|mut hcx| hasher(&mut hcx, &result));
387+
debug_assert_eq!(
388+
old_hash, new_hash,
389+
"Computed query value for {:?}({:?}) is inconsistent with fed value,\ncomputed={:#?}\nfed={:#?}",
390+
query.dep_kind, key, result, cached_result,
391+
);
392+
});
393+
}
378394
let result = job.complete(cache, result, dep_node_index);
379395
(result, Some(dep_node_index))
380396
}

0 commit comments

Comments
 (0)