Skip to content

Commit 55407b8

Browse files
committed
Auto merge of #151853 - Zalathar:feed-vtable, r=oli-obk
Use the query vtable in `query_feed` plumbing The `query_feed` function needs to be able to do two important things with (erased) query values: hash them, and debug-print them. Both of those are things that the query's vtable already knows how to do. So by passing in a vtable to `query_feed`, we can give it a nicer signature, avoid having to unerase values in the function itself, and clean up some caller-side code as well.
2 parents 79a1e77 + 09117c9 commit 55407b8

4 files changed

Lines changed: 37 additions & 41 deletions

File tree

compiler/rustc_middle/src/query/inner.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
//! Helper functions that serve as the immediate implementation of
22
//! `tcx.$query(..)` and its variations.
33
4-
use std::fmt::Debug;
5-
6-
use rustc_data_structures::fingerprint::Fingerprint;
74
use rustc_query_system::dep_graph::{DepKind, DepNodeParams};
8-
use rustc_query_system::ich::StableHashingContext;
95
use rustc_query_system::query::{QueryCache, QueryMode, try_get_cached};
106
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
117

128
use crate::dep_graph;
139
use crate::query::erase::{self, Erasable, Erased};
10+
use crate::query::plumbing::QueryVTable;
1411
use crate::ty::TyCtxt;
1512

1613
/// Shared implementation of `tcx.$query(..)` and `tcx.at(span).$query(..)`
@@ -80,35 +77,38 @@ where
8077
}
8178

8279
/// Common implementation of query feeding, used by `define_feedable!`.
83-
pub(crate) fn query_feed<'tcx, Cache, Value>(
80+
pub(crate) fn query_feed<'tcx, Cache>(
8481
tcx: TyCtxt<'tcx>,
8582
dep_kind: DepKind,
86-
hasher: Option<fn(&mut StableHashingContext<'_>, &Value) -> Fingerprint>,
83+
query_vtable: &QueryVTable<'tcx, Cache>,
8784
cache: &Cache,
8885
key: Cache::Key,
89-
erased: Erased<Value>,
86+
value: Cache::Value,
9087
) where
91-
Cache: QueryCache<Value = Erased<Value>>,
88+
Cache: QueryCache,
9289
Cache::Key: DepNodeParams<TyCtxt<'tcx>>,
93-
Value: Erasable + Debug,
9490
{
95-
let value = erase::restore_val::<Value>(erased);
91+
let format_value = query_vtable.format_value;
9692

93+
// Check whether the in-memory cache already has a value for this key.
9794
match try_get_cached(tcx, cache, &key) {
9895
Some(old) => {
99-
let old = erase::restore_val::<Value>(old);
100-
if let Some(hasher) = hasher {
101-
let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx
102-
.with_stable_hashing_context(|mut hcx| {
103-
(hasher(&mut hcx, &value), hasher(&mut hcx, &old))
104-
});
96+
// The query already has a cached value for this key.
97+
// That's OK if both values are the same, i.e. they have the same hash,
98+
// so now we check their hashes.
99+
if let Some(hasher_fn) = query_vtable.hash_result {
100+
let (old_hash, value_hash) = tcx.with_stable_hashing_context(|ref mut hcx| {
101+
(hasher_fn(hcx, &old), hasher_fn(hcx, &value))
102+
});
105103
if old_hash != value_hash {
106104
// We have an inconsistency. This can happen if one of the two
107105
// results is tainted by errors. In this case, delay a bug to
108106
// ensure compilation is doomed, and keep the `old` value.
109107
tcx.dcx().delayed_bug(format!(
110108
"Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n\
111-
old value: {old:?}\nnew value: {value:?}",
109+
old value: {old}\nnew value: {value}",
110+
old = format_value(&old),
111+
value = format_value(&value),
112112
));
113113
}
114114
} else {
@@ -117,14 +117,24 @@ pub(crate) fn query_feed<'tcx, Cache, Value>(
117117
// the query should not be marked `no_hash`.
118118
bug!(
119119
"Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n\
120-
old value: {old:?}\nnew value: {value:?}",
120+
old value: {old}\nnew value: {value}",
121+
old = format_value(&old),
122+
value = format_value(&value),
121123
)
122124
}
123125
}
124126
None => {
127+
// There is no cached value for this key, so feed the query by
128+
// adding the provided value to the cache.
125129
let dep_node = dep_graph::DepNode::construct(tcx, dep_kind, &key);
126-
let dep_node_index = tcx.dep_graph.with_feed_task(dep_node, tcx, &value, hasher);
127-
cache.complete(key, erased, dep_node_index);
130+
let dep_node_index = tcx.dep_graph.with_feed_task(
131+
dep_node,
132+
tcx,
133+
&value,
134+
query_vtable.hash_result,
135+
query_vtable.format_value,
136+
);
137+
cache.complete(key, value, dep_node_index);
128138
}
129139
}
130140
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, Trait
8787
use rustc_index::IndexVec;
8888
use rustc_lint_defs::LintId;
8989
use rustc_macros::rustc_queries;
90-
use rustc_query_system::ich::StableHashingContext;
9190
use rustc_query_system::query::{QueryMode, QueryState};
9291
use rustc_session::Limits;
9392
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -497,18 +497,6 @@ macro_rules! define_callbacks {
497497
};
498498
}
499499

500-
macro_rules! hash_result {
501-
([]) => {{
502-
Some(dep_graph::hash_result)
503-
}};
504-
([(no_hash) $($rest:tt)*]) => {{
505-
None
506-
}};
507-
([$other:tt $($modifiers:tt)*]) => {
508-
hash_result!([$($modifiers)*])
509-
};
510-
}
511-
512500
macro_rules! define_feedable {
513501
($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
514502
$(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
@@ -518,19 +506,17 @@ macro_rules! define_feedable {
518506
let key = self.key().into_query_param();
519507

520508
let tcx = self.tcx;
521-
let erased = queries::$name::provided_to_erased(tcx, value);
522-
let cache = &tcx.query_system.caches.$name;
509+
let erased_value = queries::$name::provided_to_erased(tcx, value);
523510

524511
let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
525-
let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]);
526512

527513
$crate::query::inner::query_feed(
528514
tcx,
529515
dep_kind,
530-
hasher,
531-
cache,
516+
&tcx.query_system.query_vtables.$name,
517+
&tcx.query_system.caches.$name,
532518
key,
533-
erased,
519+
erased_value,
534520
);
535521
}
536522
})*

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,12 +561,13 @@ impl<D: Deps> DepGraph<D> {
561561
/// FIXME: If the code is changed enough for this node to be marked before requiring the
562562
/// caller's node, we suppose that those changes will be enough to mark this node red and
563563
/// force a recomputation using the "normal" way.
564-
pub fn with_feed_task<Ctxt: DepContext<Deps = D>, R: Debug>(
564+
pub fn with_feed_task<Ctxt: DepContext<Deps = D>, R>(
565565
&self,
566566
node: DepNode,
567567
cx: Ctxt,
568568
result: &R,
569569
hash_result: Option<fn(&mut StableHashingContext<'_>, &R) -> Fingerprint>,
570+
format_value_fn: fn(&R) -> String,
570571
) -> DepNodeIndex {
571572
if let Some(data) = self.data.as_ref() {
572573
// The caller query has more dependencies than the node we are creating. We may
@@ -584,7 +585,7 @@ impl<D: Deps> DepGraph<D> {
584585
result,
585586
prev_index,
586587
hash_result,
587-
|value| format!("{value:?}"),
588+
format_value_fn,
588589
);
589590

590591
#[cfg(debug_assertions)]

0 commit comments

Comments
 (0)