Skip to content

Commit b135ecc

Browse files
Auto merge of #147393 - Zalathar:feed, r=<try>
Extract most code from `define_feedable!`
2 parents 1a3cdd3 + 4a43a39 commit b135ecc

File tree

2 files changed

+71
-48
lines changed

2 files changed

+71
-48
lines changed

compiler/rustc_middle/src/query/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ use std::sync::Arc;
7070
use rustc_abi::Align;
7171
use rustc_arena::TypedArena;
7272
use rustc_ast::expand::allocator::AllocatorKind;
73-
use rustc_data_structures::fingerprint::Fingerprint;
7473
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
7574
use rustc_data_structures::sorted_map::SortedMap;
7675
use rustc_data_structures::steal::Steal;
@@ -88,9 +87,7 @@ use rustc_index::IndexVec;
8887
use rustc_lint_defs::LintId;
8988
use rustc_macros::rustc_queries;
9089
use rustc_query_system::ich::StableHashingContext;
91-
use rustc_query_system::query::{
92-
QueryCache, QueryMode, QueryStackDeferred, QueryState, try_get_cached,
93-
};
90+
use rustc_query_system::query::{QueryMode, QueryStackDeferred, QueryState};
9491
use rustc_session::Limits;
9592
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
9693
use rustc_session::cstore::{

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1+
use std::fmt::Debug;
12
use std::ops::Deref;
23

4+
use rustc_data_structures::fingerprint::Fingerprint;
35
use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
46
use rustc_hir::def_id::{DefId, LocalDefId};
57
use rustc_hir::hir_id::OwnerId;
68
use rustc_macros::HashStable;
79
use rustc_query_system::HandleCycleError;
8-
use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
10+
use rustc_query_system::dep_graph::{DepNodeIndex, DepNodeParams, SerializedDepNodeIndex};
11+
use rustc_query_system::ich::StableHashingContext;
912
pub(crate) use rustc_query_system::query::QueryJobId;
1013
use rustc_query_system::query::*;
1114
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
15+
pub use sealed::IntoQueryParam;
1216

17+
use super::erase::EraseType;
1318
use crate::dep_graph;
1419
use crate::dep_graph::DepKind;
20+
use crate::query::erase::{Erase, restore};
1521
use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
1622
use crate::query::{
1723
DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
@@ -565,53 +571,77 @@ macro_rules! define_feedable {
565571

566572
let tcx = self.tcx;
567573
let erased = queries::$name::provided_to_erased(tcx, value);
568-
let value = restore::<$V>(erased);
569574
let cache = &tcx.query_system.caches.$name;
570575

576+
let name: &'static str = stringify!($name);
577+
let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
571578
let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]);
572-
match try_get_cached(tcx, cache, &key) {
573-
Some(old) => {
574-
let old = restore::<$V>(old);
575-
if let Some(hasher) = hasher {
576-
let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx|
577-
(hasher(&mut hcx, &value), hasher(&mut hcx, &old))
578-
);
579-
if old_hash != value_hash {
580-
// We have an inconsistency. This can happen if one of the two
581-
// results is tainted by errors. In this case, delay a bug to
582-
// ensure compilation is doomed, and keep the `old` value.
583-
tcx.dcx().delayed_bug(format!(
584-
"Trying to feed an already recorded value for query {} key={key:?}:\n\
585-
old value: {old:?}\nnew value: {value:?}",
586-
stringify!($name),
587-
));
588-
}
589-
} else {
590-
// The query is `no_hash`, so we have no way to perform a sanity check.
591-
// If feeding the same value multiple times needs to be supported,
592-
// the query should not be marked `no_hash`.
593-
bug!(
594-
"Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
595-
stringify!($name),
596-
)
597-
}
598-
}
599-
None => {
600-
let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::dep_kinds::$name, &key);
601-
let dep_node_index = tcx.dep_graph.with_feed_task(
602-
dep_node,
603-
tcx,
604-
&value,
605-
hash_result!([$($modifiers)*]),
606-
);
607-
cache.complete(key, erased, dep_node_index);
608-
}
609-
}
579+
580+
$crate::query::plumbing::query_feed_inner(
581+
tcx,
582+
name,
583+
dep_kind,
584+
hasher,
585+
cache,
586+
key,
587+
erased,
588+
);
610589
}
611590
})*
612591
}
613592
}
614593

594+
/// Common implementation of query feeding, used by `define_feedable!`.
595+
pub(crate) fn query_feed_inner<'tcx, Cache, Value>(
596+
tcx: TyCtxt<'tcx>,
597+
name: &'static str,
598+
dep_kind: DepKind,
599+
hasher: Option<fn(&mut StableHashingContext<'_>, &Value) -> Fingerprint>,
600+
cache: &Cache,
601+
key: Cache::Key,
602+
erased: Erase<Value>,
603+
) where
604+
Cache: QueryCache<Value = Erase<Value>>,
605+
Cache::Key: DepNodeParams<TyCtxt<'tcx>>,
606+
Value: EraseType + Debug,
607+
{
608+
let value = restore::<Value>(erased);
609+
610+
match try_get_cached(tcx, cache, &key) {
611+
Some(old) => {
612+
let old = restore::<Value>(old);
613+
if let Some(hasher) = hasher {
614+
let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx
615+
.with_stable_hashing_context(|mut hcx| {
616+
(hasher(&mut hcx, &value), hasher(&mut hcx, &old))
617+
});
618+
if old_hash != value_hash {
619+
// We have an inconsistency. This can happen if one of the two
620+
// results is tainted by errors. In this case, delay a bug to
621+
// ensure compilation is doomed, and keep the `old` value.
622+
tcx.dcx().delayed_bug(format!(
623+
"Trying to feed an already recorded value for query {name} key={key:?}:\n\
624+
old value: {old:?}\nnew value: {value:?}",
625+
));
626+
}
627+
} else {
628+
// The query is `no_hash`, so we have no way to perform a sanity check.
629+
// If feeding the same value multiple times needs to be supported,
630+
// the query should not be marked `no_hash`.
631+
bug!(
632+
"Trying to feed an already recorded value for query {name} key={key:?}:\n\
633+
old value: {old:?}\nnew value: {value:?}",
634+
)
635+
}
636+
}
637+
None => {
638+
let dep_node = dep_graph::DepNode::construct(tcx, dep_kind, &key);
639+
let dep_node_index = tcx.dep_graph.with_feed_task(dep_node, tcx, &value, hasher);
640+
cache.complete(key, erased, dep_node_index);
641+
}
642+
}
643+
}
644+
615645
// Each of these queries corresponds to a function pointer field in the
616646
// `Providers` struct for requesting a value of that type, and a method
617647
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
@@ -694,10 +724,6 @@ mod sealed {
694724
}
695725
}
696726

697-
pub use sealed::IntoQueryParam;
698-
699-
use super::erase::EraseType;
700-
701727
#[derive(Copy, Clone, Debug, HashStable)]
702728
pub struct CyclePlaceholder(pub ErrorGuaranteed);
703729

0 commit comments

Comments
 (0)