Rollup merge of #151666 - Zalathar:query-vtable, r=Kivooeo
compiler: Rename several types/traits for per-query vtables - Follow-up to https://github.com/rust-lang/rust/pull/151577 --- This is another round of renaming for some subtle types and traits used by the query system, to hopefully make them easier to understand. Key renames: - struct `DynamicQuery` → `QueryVTable` (the actual vtable-like structure) - struct `DynamicQueries` → `PerQueryVTables` (holds a vtable for each query) - trait `QueryConfig` → `QueryDispatcher` - (used by generic functions in `rustc_query_system` to interact with query vtables) - struct `DynamicConfig` → `SemiDynamicQueryDispatcher` - (implements `QueryDispatcher` by combining a vtable with some compile-time boolean flags for improved perf) - trait `QueryConfigRestored` → `UnerasedQueryDispatcher` - (provides a `QueryDispatcher` while also remembering the query's unerased value type; allows some per-query code to be moved out of macros and into generic functions) This was trickier than `DepKindVTable`, because there are more types and traits involved, and it's harder to come up with distinctive and useful names for all of them. There should be no change to compiler behaviour. r? Kivooeo (or compiler)
This commit is contained in:
commit
384a569072
7 changed files with 120 additions and 88 deletions
|
|
@ -122,7 +122,7 @@ use crate::mir::mono::{
|
|||
CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono,
|
||||
};
|
||||
use crate::query::erase::{Erase, erase, restore};
|
||||
use crate::query::plumbing::{CyclePlaceholder, DynamicQuery};
|
||||
use crate::query::plumbing::CyclePlaceholder;
|
||||
use crate::traits::query::{
|
||||
CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
|
||||
CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||
|
|
|
|||
|
|
@ -14,11 +14,14 @@ use crate::dep_graph;
|
|||
use crate::dep_graph::DepKind;
|
||||
use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
|
||||
use crate::query::{
|
||||
DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
|
||||
ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates,
|
||||
};
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
pub struct DynamicQuery<'tcx, C: QueryCache> {
|
||||
/// Stores function pointers and other metadata for a particular query.
|
||||
///
|
||||
/// Used indirectly by query plumbing in `rustc_query_system`, via a trait.
|
||||
pub struct QueryVTable<'tcx, C: QueryCache> {
|
||||
pub name: &'static str,
|
||||
pub eval_always: bool,
|
||||
pub dep_kind: DepKind,
|
||||
|
|
@ -62,7 +65,7 @@ pub struct QuerySystem<'tcx> {
|
|||
pub states: QueryStates<'tcx>,
|
||||
pub arenas: WorkerLocal<QueryArenas<'tcx>>,
|
||||
pub caches: QueryCaches<'tcx>,
|
||||
pub dynamic_queries: DynamicQueries<'tcx>,
|
||||
pub query_vtables: PerQueryVTables<'tcx>,
|
||||
|
||||
/// This provides access to the incremental compilation on-disk cache for query results.
|
||||
/// Do not access this directly. It is only meant to be used by
|
||||
|
|
@ -418,9 +421,12 @@ macro_rules! define_callbacks {
|
|||
})*
|
||||
}
|
||||
|
||||
pub struct DynamicQueries<'tcx> {
|
||||
/// Holds a `QueryVTable` for each query.
|
||||
///
|
||||
/// ("Per" just makes this pluralized name more visually distinct.)
|
||||
pub struct PerQueryVTables<'tcx> {
|
||||
$(
|
||||
pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>>,
|
||||
pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, queries::$name::Storage<'tcx>>,
|
||||
)*
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,17 +12,16 @@ use rustc_middle::arena::Arena;
|
|||
use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNodeIndex};
|
||||
use rustc_middle::query::erase::{Erase, erase, restore};
|
||||
use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
|
||||
use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns};
|
||||
use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable};
|
||||
use rustc_middle::query::{
|
||||
AsLocalKey, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates,
|
||||
queries,
|
||||
AsLocalKey, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, queries,
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_query_system::Value;
|
||||
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_query_system::query::{
|
||||
CycleError, CycleErrorHandling, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode,
|
||||
CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode,
|
||||
QueryStackDeferred, QueryState, get_query_incr, get_query_non_incr,
|
||||
};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
|
@ -37,30 +36,39 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
|
|||
mod profiling_support;
|
||||
pub use self::profiling_support::alloc_self_profile_query_strings;
|
||||
|
||||
struct DynamicConfig<
|
||||
/// Combines a [`QueryVTable`] with some additional compile-time booleans
|
||||
/// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`].
|
||||
///
|
||||
/// Baking these boolean flags into the type gives a modest but measurable
|
||||
/// improvement to compiler perf and compiler code size; see
|
||||
/// <https://github.com/rust-lang/rust/pull/151633>.
|
||||
struct SemiDynamicQueryDispatcher<
|
||||
'tcx,
|
||||
C: QueryCache,
|
||||
const ANON: bool,
|
||||
const DEPTH_LIMIT: bool,
|
||||
const FEEDABLE: bool,
|
||||
> {
|
||||
dynamic: &'tcx DynamicQuery<'tcx, C>,
|
||||
vtable: &'tcx QueryVTable<'tcx, C>,
|
||||
}
|
||||
|
||||
// Manually implement Copy/Clone, because deriving would put trait bounds on the cache type.
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy
|
||||
for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
{
|
||||
}
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone
|
||||
for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
// This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`.
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool>
|
||||
QueryConfig<QueryCtxt<'tcx>> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
QueryDispatcher<QueryCtxt<'tcx>>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
where
|
||||
for<'a> C::Key: HashStable<StableHashingContext<'a>>,
|
||||
{
|
||||
|
|
@ -70,12 +78,12 @@ where
|
|||
|
||||
#[inline(always)]
|
||||
fn name(self) -> &'static str {
|
||||
self.dynamic.name
|
||||
self.vtable.name
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
|
||||
(self.dynamic.cache_on_disk)(tcx, key)
|
||||
(self.vtable.cache_on_disk)(tcx, key)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
@ -90,7 +98,7 @@ where
|
|||
// This is just manually doing the subfield referencing through pointer math.
|
||||
unsafe {
|
||||
&*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>)
|
||||
.byte_add(self.dynamic.query_state)
|
||||
.byte_add(self.vtable.query_state)
|
||||
.cast::<QueryState<Self::Key, QueryStackDeferred<'tcx>>>()
|
||||
}
|
||||
}
|
||||
|
|
@ -104,19 +112,19 @@ where
|
|||
// This is just manually doing the subfield referencing through pointer math.
|
||||
unsafe {
|
||||
&*(&qcx.tcx.query_system.caches as *const QueryCaches<'tcx>)
|
||||
.byte_add(self.dynamic.query_cache)
|
||||
.byte_add(self.vtable.query_cache)
|
||||
.cast::<Self::Cache>()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
|
||||
(self.dynamic.execute_query)(tcx, key)
|
||||
(self.vtable.execute_query)(tcx, key)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
|
||||
(self.dynamic.compute)(qcx.tcx, key)
|
||||
(self.vtable.compute)(qcx.tcx, key)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
@ -127,8 +135,8 @@ where
|
|||
prev_index: SerializedDepNodeIndex,
|
||||
index: DepNodeIndex,
|
||||
) -> Option<Self::Value> {
|
||||
if self.dynamic.can_load_from_disk {
|
||||
(self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index)
|
||||
if self.vtable.can_load_from_disk {
|
||||
(self.vtable.try_load_from_disk)(qcx.tcx, key, prev_index, index)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -141,7 +149,7 @@ where
|
|||
key: &Self::Key,
|
||||
index: SerializedDepNodeIndex,
|
||||
) -> bool {
|
||||
(self.dynamic.loadable_from_disk)(qcx.tcx, key, index)
|
||||
(self.vtable.loadable_from_disk)(qcx.tcx, key, index)
|
||||
}
|
||||
|
||||
fn value_from_cycle_error(
|
||||
|
|
@ -150,12 +158,12 @@ where
|
|||
cycle_error: &CycleError,
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self::Value {
|
||||
(self.dynamic.value_from_cycle_error)(tcx, cycle_error, guar)
|
||||
(self.vtable.value_from_cycle_error)(tcx, cycle_error, guar)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn format_value(self) -> fn(&Self::Value) -> String {
|
||||
self.dynamic.format_value
|
||||
self.vtable.format_value
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
@ -165,7 +173,7 @@ where
|
|||
|
||||
#[inline(always)]
|
||||
fn eval_always(self) -> bool {
|
||||
self.dynamic.eval_always
|
||||
self.vtable.eval_always
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
@ -180,31 +188,42 @@ where
|
|||
|
||||
#[inline(always)]
|
||||
fn dep_kind(self) -> DepKind {
|
||||
self.dynamic.dep_kind
|
||||
self.vtable.dep_kind
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn cycle_error_handling(self) -> CycleErrorHandling {
|
||||
self.dynamic.cycle_error_handling
|
||||
self.vtable.cycle_error_handling
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn hash_result(self) -> HashResult<Self::Value> {
|
||||
self.dynamic.hash_result
|
||||
self.vtable.hash_result
|
||||
}
|
||||
}
|
||||
|
||||
/// This is implemented per query. It allows restoring query values from their erased state
|
||||
/// and constructing a QueryConfig.
|
||||
trait QueryConfigRestored<'tcx> {
|
||||
type RestoredValue;
|
||||
type Config: QueryConfig<QueryCtxt<'tcx>>;
|
||||
/// Provides access to vtable-like operations for a query
|
||||
/// (by creating a [`QueryDispatcher`]),
|
||||
/// but also keeps track of the "unerased" value type of the query
|
||||
/// (i.e. the actual result type in the query declaration).
|
||||
///
|
||||
/// This trait allows some per-query code to be defined in generic functions
|
||||
/// with a trait bound, instead of having to be defined inline within a macro
|
||||
/// expansion.
|
||||
///
|
||||
/// There is one macro-generated implementation of this trait for each query,
|
||||
/// on the type `rustc_query_impl::query_impl::$name::QueryType`.
|
||||
trait QueryDispatcherUnerased<'tcx> {
|
||||
type UnerasedValue;
|
||||
type Dispatcher: QueryDispatcher<QueryCtxt<'tcx>>;
|
||||
|
||||
const NAME: &'static &'static str;
|
||||
|
||||
fn config(tcx: TyCtxt<'tcx>) -> Self::Config;
|
||||
fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value)
|
||||
-> Self::RestoredValue;
|
||||
fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher;
|
||||
|
||||
fn restore_val(
|
||||
value: <Self::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Value,
|
||||
) -> Self::UnerasedValue;
|
||||
}
|
||||
|
||||
pub fn query_system<'a>(
|
||||
|
|
@ -217,7 +236,7 @@ pub fn query_system<'a>(
|
|||
states: Default::default(),
|
||||
arenas: Default::default(),
|
||||
caches: Default::default(),
|
||||
dynamic_queries: dynamic_queries(),
|
||||
query_vtables: make_query_vtables(),
|
||||
on_disk_cache,
|
||||
fns: QuerySystemFns {
|
||||
engine: engine(incremental),
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ 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::{
|
||||
QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect,
|
||||
QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect,
|
||||
QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query,
|
||||
};
|
||||
use rustc_query_system::{QueryOverflow, QueryOverflowNote};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
|
||||
use crate::QueryConfigRestored;
|
||||
use crate::QueryDispatcherUnerased;
|
||||
|
||||
/// Implements [`QueryContext`] for use by [`rustc_query_system`], since that
|
||||
/// crate does not have direct access to [`TyCtxt`].
|
||||
|
|
@ -387,13 +387,13 @@ pub(crate) fn create_query_frame<
|
|||
}
|
||||
|
||||
pub(crate) fn encode_query_results<'a, 'tcx, Q>(
|
||||
query: Q::Config,
|
||||
query: Q::Dispatcher,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
encoder: &mut CacheEncoder<'a, 'tcx>,
|
||||
query_result_index: &mut EncodedDepNodeIndex,
|
||||
) where
|
||||
Q: super::QueryConfigRestored<'tcx>,
|
||||
Q::RestoredValue: Encodable<CacheEncoder<'a, 'tcx>>,
|
||||
Q: QueryDispatcherUnerased<'tcx>,
|
||||
Q::UnerasedValue: Encodable<CacheEncoder<'a, 'tcx>>,
|
||||
{
|
||||
let _timer = qcx.tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name());
|
||||
|
||||
|
|
@ -408,13 +408,13 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>(
|
|||
|
||||
// Encode the type check tables with the `SerializedDepNodeIndex`
|
||||
// as tag.
|
||||
encoder.encode_tagged(dep_node, &Q::restore(*value));
|
||||
encoder.encode_tagged(dep_node, &Q::restore_val(*value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn query_key_hash_verify<'tcx>(
|
||||
query: impl QueryConfig<QueryCtxt<'tcx>>,
|
||||
query: impl QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
) {
|
||||
let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name());
|
||||
|
|
@ -442,7 +442,7 @@ pub(crate) fn query_key_hash_verify<'tcx>(
|
|||
|
||||
fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode)
|
||||
where
|
||||
Q: QueryConfig<QueryCtxt<'tcx>>,
|
||||
Q: QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
{
|
||||
debug_assert!(tcx.dep_graph.is_green(&dep_node));
|
||||
|
||||
|
|
@ -488,7 +488,7 @@ where
|
|||
|
||||
fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
|
||||
where
|
||||
Q: QueryConfig<QueryCtxt<'tcx>>,
|
||||
Q: QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
{
|
||||
// We must avoid ever having to call `force_from_dep_node()` for a
|
||||
// `DepNode::codegen_unit`:
|
||||
|
|
@ -521,9 +521,10 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>(
|
|||
is_eval_always: bool,
|
||||
) -> DepKindVTable<'tcx>
|
||||
where
|
||||
Q: QueryConfigRestored<'tcx>,
|
||||
Q: QueryDispatcherUnerased<'tcx>,
|
||||
{
|
||||
let fingerprint_style = <Q::Config as QueryConfig<QueryCtxt<'tcx>>>::Key::fingerprint_style();
|
||||
let fingerprint_style =
|
||||
<Q::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Key::fingerprint_style();
|
||||
|
||||
if is_anon || !fingerprint_style.reconstructible() {
|
||||
return DepKindVTable {
|
||||
|
|
@ -541,10 +542,10 @@ where
|
|||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: Some(|tcx, dep_node, _| {
|
||||
force_from_dep_node(Q::config(tcx), tcx, dep_node)
|
||||
force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
|
||||
try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node)
|
||||
try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
name: Q::NAME,
|
||||
}
|
||||
|
|
@ -613,7 +614,7 @@ macro_rules! define_queries {
|
|||
#[cfg(debug_assertions)]
|
||||
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
|
||||
get_query_incr(
|
||||
QueryType::config(tcx),
|
||||
QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
span,
|
||||
key,
|
||||
|
|
@ -633,7 +634,7 @@ macro_rules! define_queries {
|
|||
__mode: QueryMode,
|
||||
) -> Option<Erase<queries::$name::Value<'tcx>>> {
|
||||
Some(get_query_non_incr(
|
||||
QueryType::config(tcx),
|
||||
QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
span,
|
||||
key,
|
||||
|
|
@ -641,10 +642,10 @@ macro_rules! define_queries {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn dynamic_query<'tcx>()
|
||||
-> DynamicQuery<'tcx, queries::$name::Storage<'tcx>>
|
||||
pub(crate) fn make_query_vtable<'tcx>()
|
||||
-> QueryVTable<'tcx, queries::$name::Storage<'tcx>>
|
||||
{
|
||||
DynamicQuery {
|
||||
QueryVTable {
|
||||
name: stringify!($name),
|
||||
eval_always: is_eval_always!([$($modifiers)*]),
|
||||
dep_kind: dep_graph::dep_kinds::$name,
|
||||
|
|
@ -710,9 +711,9 @@ macro_rules! define_queries {
|
|||
data: PhantomData<&'tcx ()>
|
||||
}
|
||||
|
||||
impl<'tcx> QueryConfigRestored<'tcx> for QueryType<'tcx> {
|
||||
type RestoredValue = queries::$name::Value<'tcx>;
|
||||
type Config = DynamicConfig<
|
||||
impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> {
|
||||
type UnerasedValue = queries::$name::Value<'tcx>;
|
||||
type Dispatcher = SemiDynamicQueryDispatcher<
|
||||
'tcx,
|
||||
queries::$name::Storage<'tcx>,
|
||||
{ is_anon!([$($modifiers)*]) },
|
||||
|
|
@ -723,14 +724,14 @@ macro_rules! define_queries {
|
|||
const NAME: &'static &'static str = &stringify!($name);
|
||||
|
||||
#[inline(always)]
|
||||
fn config(tcx: TyCtxt<'tcx>) -> Self::Config {
|
||||
DynamicConfig {
|
||||
dynamic: &tcx.query_system.dynamic_queries.$name,
|
||||
fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher {
|
||||
SemiDynamicQueryDispatcher {
|
||||
vtable: &tcx.query_system.query_vtables.$name,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue {
|
||||
fn restore_val(value: <Self::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Value) -> Self::UnerasedValue {
|
||||
restore::<queries::$name::Value<'tcx>>(value)
|
||||
}
|
||||
}
|
||||
|
|
@ -782,7 +783,7 @@ macro_rules! define_queries {
|
|||
query_result_index: &mut EncodedDepNodeIndex
|
||||
) {
|
||||
$crate::plumbing::encode_query_results::<query_impl::$name::QueryType<'tcx>>(
|
||||
query_impl::$name::QueryType::config(tcx),
|
||||
query_impl::$name::QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
encoder,
|
||||
query_result_index,
|
||||
|
|
@ -792,7 +793,7 @@ macro_rules! define_queries {
|
|||
|
||||
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
$crate::plumbing::query_key_hash_verify(
|
||||
query_impl::$name::QueryType::config(tcx),
|
||||
query_impl::$name::QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
)
|
||||
}
|
||||
|
|
@ -810,10 +811,10 @@ macro_rules! define_queries {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn dynamic_queries<'tcx>() -> DynamicQueries<'tcx> {
|
||||
DynamicQueries {
|
||||
pub fn make_query_vtables<'tcx>() -> ::rustc_middle::query::PerQueryVTables<'tcx> {
|
||||
::rustc_middle::query::PerQueryVTables {
|
||||
$(
|
||||
$name: query_impl::$name::dynamic_query(),
|
||||
$name: query_impl::$name::make_query_vtable(),
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
//! Query configuration and description traits.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
|
@ -14,7 +12,15 @@ use crate::query::{CycleError, CycleErrorHandling, DepNodeIndex, QueryContext, Q
|
|||
|
||||
pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>;
|
||||
|
||||
pub trait QueryConfig<Qcx: QueryContext>: Copy {
|
||||
/// Trait that can be used as a vtable for a single query, providing operations
|
||||
/// and metadata for that query.
|
||||
///
|
||||
/// Implemented by `rustc_query_impl::SemiDynamicQueryDispatcher`, which
|
||||
/// mostly delegates to `rustc_middle::query::plumbing::QueryVTable`.
|
||||
/// Those types are not visible from this `rustc_query_system` crate.
|
||||
///
|
||||
/// "Dispatcher" should be understood as a near-synonym of "vtable".
|
||||
pub trait QueryDispatcher<Qcx: QueryContext>: Copy {
|
||||
fn name(self) -> &'static str;
|
||||
|
||||
// `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap,
|
||||
|
|
@ -13,7 +13,7 @@ use rustc_span::Span;
|
|||
use rustc_span::def_id::DefId;
|
||||
|
||||
pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
|
||||
pub use self::config::{HashResult, QueryConfig};
|
||||
pub use self::dispatcher::{HashResult, QueryDispatcher};
|
||||
pub use self::job::{
|
||||
QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack,
|
||||
report_cycle,
|
||||
|
|
@ -22,7 +22,7 @@ pub use self::plumbing::*;
|
|||
use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
|
||||
|
||||
mod caches;
|
||||
mod config;
|
||||
mod dispatcher;
|
||||
mod job;
|
||||
mod plumbing;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use rustc_errors::{Diag, FatalError, StashKey};
|
|||
use rustc_span::{DUMMY_SP, Span};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::{QueryConfig, QueryStackFrameExtra};
|
||||
use super::{QueryDispatcher, QueryStackFrameExtra};
|
||||
use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::query::caches::QueryCache;
|
||||
|
|
@ -126,7 +126,7 @@ where
|
|||
#[inline(never)]
|
||||
fn mk_cycle<Q, Qcx>(query: Q, qcx: Qcx, cycle_error: CycleError) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
let error = report_cycle(qcx.dep_context().sess(), &cycle_error);
|
||||
|
|
@ -140,7 +140,7 @@ fn handle_cycle_error<Q, Qcx>(
|
|||
error: Diag<'_>,
|
||||
) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
match query.cycle_error_handling() {
|
||||
|
|
@ -279,7 +279,7 @@ fn cycle_error<Q, Qcx>(
|
|||
span: Span,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Ensure there was no errors collecting all active jobs.
|
||||
|
|
@ -300,7 +300,7 @@ fn wait_for_query<Q, Qcx>(
|
|||
current: Option<QueryJobId>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// For parallel queries, we'll block and wait until the query running
|
||||
|
|
@ -349,7 +349,7 @@ fn try_execute_query<Q, Qcx, const INCR: bool>(
|
|||
dep_node: Option<DepNode>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
let state = query.query_state(qcx);
|
||||
|
|
@ -421,7 +421,7 @@ fn execute_job<Q, Qcx, const INCR: bool>(
|
|||
dep_node: Option<DepNode>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Use `JobOwner` so the query will be poisoned if executing it panics.
|
||||
|
|
@ -491,7 +491,7 @@ fn execute_job_non_incr<Q, Qcx>(
|
|||
job_id: QueryJobId,
|
||||
) -> (Q::Value, DepNodeIndex)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -530,7 +530,7 @@ fn execute_job_incr<Q, Qcx>(
|
|||
job_id: QueryJobId,
|
||||
) -> (Q::Value, DepNodeIndex)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
if !query.anon() && !query.eval_always() {
|
||||
|
|
@ -585,7 +585,7 @@ fn try_load_from_disk_and_cache_in_memory<Q, Qcx>(
|
|||
dep_node: &DepNode,
|
||||
) -> Option<(Q::Value, DepNodeIndex)>
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Note this function can be called concurrently from the same query
|
||||
|
|
@ -771,7 +771,7 @@ fn ensure_must_run<Q, Qcx>(
|
|||
check_cache: bool,
|
||||
) -> (bool, Option<DepNode>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
if query.eval_always() {
|
||||
|
|
@ -819,7 +819,7 @@ pub enum QueryMode {
|
|||
#[inline(always)]
|
||||
pub fn get_query_non_incr<Q, Qcx>(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -836,7 +836,7 @@ pub fn get_query_incr<Q, Qcx>(
|
|||
mode: QueryMode,
|
||||
) -> Option<Q::Value>
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -862,7 +862,7 @@ where
|
|||
|
||||
pub fn force_query<Q, Qcx>(query: Q, qcx: Qcx, key: Q::Key, dep_node: DepNode)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// We may be concurrently trying both execute and force a query.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue