use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lock;
use rustc_errors::{Diagnostic, Handler};
-use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex};
+use rustc_middle::dep_graph::{
+ self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
+};
use rustc_middle::ty::tls::{self, ImplicitCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
use rustc_query_system::ich::StableHashingContext;
use rustc_query_system::query::{
- force_query, QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects,
- QueryStackFrame,
+ force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
+ QuerySideEffects, QueryStackFrame,
};
+use rustc_query_system::Value;
use std::any::Any;
use std::num::NonZeroU64;
use thin_vec::ThinVec;
}
macro_rules! handle_cycle_error {
- ([][$tcx: expr, $error:expr]) => {{
- $error.emit();
- Value::from_cycle_error($tcx)
+ ([]) => {{
+ rustc_query_system::HandleCycleError::Error
}};
- ([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.emit();
- $tcx.sess.abort_if_errors();
- unreachable!()
+ ([(fatal_cycle) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::Fatal
}};
- ([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.delay_as_bug();
- Value::from_cycle_error($tcx)
+ ([(cycle_delay_bug) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::DelayBug
}};
- ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
- handle_cycle_error!([$($modifiers)*][$($args)*])
+ ([$other:tt $($modifiers:tt)*]) => {
+ handle_cycle_error!([$($modifiers)*])
};
}
QueryStackFrame::new(name, description, span, def_kind, hash)
}
-pub(crate) fn try_load_from_on_disk_cache<'tcx, K: DepNodeParams<TyCtxt<'tcx>>, V>(
- tcx: TyCtxt<'tcx>,
- dep_node: DepNode,
- cache_on_disk: fn(TyCtxt<'tcx>, &K) -> bool,
- do_query: fn(TyCtxt<'tcx>, K) -> V,
-) {
+fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode)
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
debug_assert!(tcx.dep_graph.is_green(&dep_node));
- let key = K::recover(tcx, &dep_node).unwrap_or_else(|| {
+ let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
});
- if cache_on_disk(tcx, &key) {
- let _ = do_query(tcx, key);
+ if Q::cache_on_disk(tcx, &key) {
+ let _ = Q::execute_query(tcx, key);
}
}
where
Q: QueryDescription<QueryCtxt<'tcx>>,
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+ Q::Value: Value<TyCtxt<'tcx>>,
{
if let Some(key) = Q::Key::recover(tcx, &dep_node) {
#[cfg(debug_assertions)]
}
}
+pub(crate) fn query_callback<'tcx, Q: QueryConfig>(
+ is_anon: bool,
+ is_eval_always: bool,
+) -> DepKindStruct<'tcx>
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
+ let fingerprint_style = Q::Key::fingerprint_style();
+
+ if is_anon || !fingerprint_style.reconstructible() {
+ return DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: None,
+ try_load_from_on_disk_cache: None,
+ };
+ }
+
+ DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: Some(force_from_dep_node::<Q>),
+ try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::<Q>),
+ }
+}
+
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
// invoked by `rustc_query_append`.
macro_rules! define_queries {
depth_limit: depth_limit!([$($modifiers)*]),
dep_kind: dep_graph::DepKind::$name,
hash_result: hash_result!([$($modifiers)*]),
- handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]),
+ handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
compute,
cache_on_disk,
try_load_from_disk: Self::TRY_LOAD_FROM_DISK,
}
}
+
+ fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored {
+ tcx.$name(k)
+ }
})*
#[allow(nonstandard_style)]
mod query_callbacks {
use super::*;
- use rustc_query_system::dep_graph::DepNodeParams;
- use rustc_query_system::query::QueryDescription;
use rustc_query_system::dep_graph::FingerprintStyle;
// We use this for most things when incr. comp. is turned off.
- pub fn Null() -> DepKindStruct {
+ pub fn Null<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
}
// We use this for the forever-red node.
- pub fn Red() -> DepKindStruct {
+ pub fn Red<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
}
}
- pub fn TraitSelect() -> DepKindStruct {
+ pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: true,
is_eval_always: false,
}
}
- pub fn CompileCodegenUnit() -> DepKindStruct {
+ pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
}
}
- pub fn CompileMonoItem() -> DepKindStruct {
+ pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
}
}
- $(pub(crate) fn $name()-> DepKindStruct {
- let is_anon = is_anon!([$($modifiers)*]);
- let is_eval_always = is_eval_always!([$($modifiers)*]);
-
- let fingerprint_style =
- <<queries::$name<'_> as QueryConfig>::Key as DepNodeParams<TyCtxt<'_>>>::fingerprint_style();
-
- if is_anon || !fingerprint_style.reconstructible() {
- return DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: None,
- try_load_from_on_disk_cache: None,
- }
- }
-
- DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: Some(|tcx, dep_node| $crate::plumbing::force_from_dep_node::<queries::$name<'_>>(tcx, dep_node)),
- try_load_from_on_disk_cache: Some(|tcx, key| $crate::plumbing::try_load_from_on_disk_cache::<
- <queries::$name<'_> as QueryConfig>::Key, _
- >(tcx, key, queries::$name::cache_on_disk, TyCtxt::$name)),
- }
+ $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
+ $crate::plumbing::query_callback::<queries::$name<'tcx>>(
+ is_anon!([$($modifiers)*]),
+ is_eval_always!([$($modifiers)*]),
+ )
})*
}
- pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] {
+ pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
}
}