//! Query configuration and description traits. use crate::dep_graph::DepNode; use crate::dep_graph::SerializedDepNodeIndex; use crate::query::caches::QueryCache; use crate::query::plumbing::CycleError; use crate::query::{QueryCacheStore, QueryContext, QueryState}; use rustc_data_structures::fingerprint::Fingerprint; use std::fmt::Debug; use std::hash::Hash; pub trait QueryConfig { const NAME: &'static str; type Key: Eq + Hash + Clone + Debug; type Value; type Stored: Clone; } pub(crate) struct QueryVtable { pub anon: bool, pub dep_kind: CTX::DepKind, pub eval_always: bool, // Don't use this method to compute query results, instead use the methods on TyCtxt pub compute: fn(CTX, K) -> V, pub hash_result: fn(&mut CTX::StableHashingContext, &V) -> Option, pub handle_cycle_error: fn(CTX, CycleError) -> V, pub cache_on_disk: fn(CTX, &K, Option<&V>) -> bool, pub try_load_from_disk: fn(CTX, SerializedDepNodeIndex) -> Option, } impl QueryVtable { pub(crate) fn to_dep_node(&self, tcx: CTX::DepContext, key: &K) -> DepNode where K: crate::dep_graph::DepNodeParams, { DepNode::construct(tcx, self.dep_kind, key) } pub(crate) fn compute(&self, tcx: CTX, key: K) -> V { (self.compute)(tcx, key) } pub(crate) fn hash_result( &self, hcx: &mut CTX::StableHashingContext, value: &V, ) -> Option { (self.hash_result)(hcx, value) } pub(crate) fn handle_cycle_error(&self, tcx: CTX, error: CycleError) -> V { (self.handle_cycle_error)(tcx, error) } pub(crate) fn cache_on_disk(&self, tcx: CTX, key: &K, value: Option<&V>) -> bool { (self.cache_on_disk)(tcx, key, value) } pub(crate) fn try_load_from_disk(&self, tcx: CTX, index: SerializedDepNodeIndex) -> Option { (self.try_load_from_disk)(tcx, index) } } pub trait QueryAccessors: QueryConfig { const ANON: bool; const EVAL_ALWAYS: bool; const DEP_KIND: CTX::DepKind; type Cache: QueryCache; // Don't use this method to access query results, instead use the methods on TyCtxt fn query_state<'a>(tcx: CTX) -> &'a QueryState; // Don't use this method to access query results, instead use the methods on TyCtxt fn query_cache<'a>(tcx: CTX) -> &'a QueryCacheStore where CTX: 'a; // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: CTX, key: Self::Key) -> Self::Value; fn hash_result( hcx: &mut CTX::StableHashingContext, result: &Self::Value, ) -> Option; fn handle_cycle_error(tcx: CTX, error: CycleError) -> Self::Value; } pub trait QueryDescription: QueryAccessors { fn describe(tcx: CTX, key: Self::Key) -> String; #[inline] fn cache_on_disk(_: CTX, _: &Self::Key, _: Option<&Self::Value>) -> bool { false } fn try_load_from_disk(_: CTX, _: SerializedDepNodeIndex) -> Option { panic!("QueryDescription::load_from_disk() called for an unsupported query.") } } pub(crate) trait QueryVtableExt { const VTABLE: QueryVtable; } impl QueryVtableExt for Q where CTX: QueryContext, Q: QueryDescription, { const VTABLE: QueryVtable = QueryVtable { anon: Q::ANON, dep_kind: Q::DEP_KIND, eval_always: Q::EVAL_ALWAYS, compute: Q::compute, hash_result: Q::hash_result, handle_cycle_error: Q::handle_cycle_error, cache_on_disk: Q::cache_on_disk, try_load_from_disk: Q::try_load_from_disk, }; }