diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty')
-rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 8 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/context/tls.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 9 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/query.rs | 640 |
6 files changed, 11 insertions, 654 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 097bfb71a6f..e84d0100a5c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,14 +14,14 @@ use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; +use crate::query::plumbing::QuerySystem; use crate::query::LocalCrate; use crate::query::Providers; +use crate::query::{IntoQueryParam, TyCtxtAt}; use crate::thir::Thir; use crate::traits; use crate::traits::solve; use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData}; -use crate::ty::query::QuerySystem; -use crate::ty::query::{self, TyCtxtAt}; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, @@ -80,8 +80,6 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; -use super::query::IntoQueryParam; - const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); #[allow(rustc::usage_of_ty_tykind)] @@ -512,7 +510,7 @@ pub struct GlobalCtxt<'tcx> { untracked: Untracked, - pub query_system: query::QuerySystem<'tcx>, + pub query_system: QuerySystem<'tcx>, pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index bf9806f6406..5c1c419811e 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -1,7 +1,7 @@ use super::{GlobalCtxt, TyCtxt}; use crate::dep_graph::TaskDepsRef; -use crate::ty::query; +use crate::query::plumbing::QueryJobId; use rustc_data_structures::sync::{self, Lock}; use rustc_errors::Diagnostic; #[cfg(not(parallel_compiler))] @@ -22,7 +22,7 @@ pub struct ImplicitCtxt<'a, 'tcx> { /// The current query job, if any. This is updated by `JobOwner::start` in /// `ty::query::plumbing` when executing a query. - pub query: Option<query::QueryJobId>, + pub query: Option<QueryJobId>, /// Where to store diagnostics for the current query job, if any. /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 47cf48f46cf..ba91e5aea5a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,5 +1,6 @@ use crate::fluent_generated as fluent; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; @@ -543,20 +544,20 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> { } } -impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasDataLayout for TyCtxtAt<'tcx> { #[inline] fn data_layout(&self) -> &TargetDataLayout { &self.data_layout } } -impl<'tcx> HasTargetSpec for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTargetSpec for TyCtxtAt<'tcx> { fn target_spec(&self) -> &Target { &self.sess.target } } -impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { **self @@ -683,7 +684,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { } } -impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { +impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> { type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>; #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index df324bcc52c..be0d1e61a46 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -122,8 +122,6 @@ pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; pub mod print; -#[macro_use] -pub mod query; pub mod relate; pub mod subst; pub mod trait_def; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a8193c3e559..4491d78648f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,6 +1,6 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::query::IntoQueryParam; use crate::query::Providers; -use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs deleted file mode 100644 index 647f4826876..00000000000 --- a/compiler/rustc_middle/src/ty/query.rs +++ /dev/null @@ -1,640 +0,0 @@ -use crate::dep_graph; -use crate::dep_graph::DepKind; -use crate::query::on_disk_cache::CacheEncoder; -use crate::query::on_disk_cache::EncodedDepNodeIndex; -use crate::query::on_disk_cache::OnDiskCache; -use crate::query::{ - DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, -}; -use crate::ty::TyCtxt; -use field_offset::FieldOffset; -use measureme::StringId; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::AtomicU64; -use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::hir_id::OwnerId; -use rustc_query_system::dep_graph::DepNodeIndex; -use rustc_query_system::dep_graph::SerializedDepNodeIndex; -pub(crate) use rustc_query_system::query::QueryJobId; -use rustc_query_system::query::*; -use rustc_query_system::HandleCycleError; -use rustc_span::{Span, DUMMY_SP}; -use std::ops::Deref; - -pub struct QueryKeyStringCache { - pub def_id_cache: FxHashMap<DefId, StringId>, -} - -impl QueryKeyStringCache { - pub fn new() -> QueryKeyStringCache { - QueryKeyStringCache { def_id_cache: Default::default() } - } -} - -#[derive(Clone, Copy)] -pub struct QueryStruct<'tcx> { - pub try_collect_active_jobs: fn(TyCtxt<'tcx>, &mut QueryMap<DepKind>) -> Option<()>, - pub alloc_self_profile_query_strings: fn(TyCtxt<'tcx>, &mut QueryKeyStringCache), - pub encode_query_results: - Option<fn(TyCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>, -} - -pub struct DynamicQuery<'tcx, C: QueryCache> { - pub name: &'static str, - pub eval_always: bool, - pub dep_kind: rustc_middle::dep_graph::DepKind, - pub handle_cycle_error: HandleCycleError, - pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, crate::dep_graph::DepKind>>, - pub query_cache: FieldOffset<QueryCaches<'tcx>, C>, - pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool, - pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value, - pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, - pub can_load_from_disk: bool, - pub try_load_from_disk: fn( - tcx: TyCtxt<'tcx>, - key: &C::Key, - prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, - ) -> Option<C::Value>, - pub loadable_from_disk: - fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool, - pub hash_result: HashResult<C::Value>, - pub value_from_cycle_error: - fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<crate::dep_graph::DepKind>]) -> C::Value, - pub format_value: fn(&C::Value) -> String, -} - -pub struct QuerySystemFns<'tcx> { - pub engine: QueryEngine, - pub local_providers: Providers, - pub extern_providers: ExternProviders, - pub query_structs: Vec<QueryStruct<'tcx>>, - pub encode_query_results: fn( - tcx: TyCtxt<'tcx>, - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, - ), - pub try_mark_green: fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool, -} - -pub struct QuerySystem<'tcx> { - pub states: QueryStates<'tcx>, - pub arenas: QueryArenas<'tcx>, - pub caches: QueryCaches<'tcx>, - pub dynamic_queries: DynamicQueries<'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 - /// `DepGraph::try_mark_green()` and the query infrastructure. - /// This is `None` if we are not incremental compilation mode - pub on_disk_cache: Option<OnDiskCache<'tcx>>, - - pub fns: QuerySystemFns<'tcx>, - - pub jobs: AtomicU64, -} - -#[derive(Copy, Clone)] -pub struct TyCtxtAt<'tcx> { - pub tcx: TyCtxt<'tcx>, - pub span: Span, -} - -impl<'tcx> Deref for TyCtxtAt<'tcx> { - type Target = TyCtxt<'tcx>; - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.tcx - } -} - -#[derive(Copy, Clone)] -pub struct TyCtxtEnsure<'tcx> { - pub tcx: TyCtxt<'tcx>, -} - -#[derive(Copy, Clone)] -pub struct TyCtxtEnsureWithValue<'tcx> { - pub tcx: TyCtxt<'tcx>, -} - -impl<'tcx> TyCtxt<'tcx> { - /// Returns a transparent wrapper for `TyCtxt`, which ensures queries - /// are executed instead of just returning their results. - #[inline(always)] - pub fn ensure(self) -> TyCtxtEnsure<'tcx> { - TyCtxtEnsure { tcx: self } - } - - /// Returns a transparent wrapper for `TyCtxt`, which ensures queries - /// are executed instead of just returning their results. - /// - /// This version verifies that the computed result exists in the cache before returning. - #[inline(always)] - pub fn ensure_with_value(self) -> TyCtxtEnsureWithValue<'tcx> { - TyCtxtEnsureWithValue { tcx: self } - } - - /// Returns a transparent wrapper for `TyCtxt` which uses - /// `span` as the location of queries performed through it. - #[inline(always)] - pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { - TyCtxtAt { tcx: self, span } - } - - pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool { - (self.query_system.fns.try_mark_green)(self, dep_node) - } -} - -#[inline] -pub fn query_get_at<'tcx, Cache>( - tcx: TyCtxt<'tcx>, - execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>, - query_cache: &Cache, - span: Span, - key: Cache::Key, -) -> Cache::Value -where - Cache: QueryCache, -{ - let key = key.into_query_param(); - match try_get_cached(tcx, query_cache, &key) { - Some(value) => value, - None => execute_query(tcx, span, key, QueryMode::Get).unwrap(), - } -} - -#[inline] -pub fn query_ensure<'tcx, Cache>( - tcx: TyCtxt<'tcx>, - execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>, - query_cache: &Cache, - key: Cache::Key, - check_cache: bool, -) where - Cache: QueryCache, -{ - let key = key.into_query_param(); - if try_get_cached(tcx, query_cache, &key).is_none() { - execute_query(tcx, DUMMY_SP, key, QueryMode::Ensure { check_cache }); - } -} - -macro_rules! query_helper_param_ty { - (DefId) => { impl IntoQueryParam<DefId> }; - (LocalDefId) => { impl IntoQueryParam<LocalDefId> }; - ($K:ty) => { $K }; -} - -macro_rules! query_if_arena { - ([] $arena:tt $no_arena:tt) => { - $no_arena - }; - ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => { - $arena - }; - ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { - query_if_arena!([$($modifiers)*]$($args)*) - }; -} - -/// If `separate_provide_if_extern`, then the key can be projected to its -/// local key via `<$K as AsLocalKey>::LocalKey`. -macro_rules! local_key_if_separate_extern { - ([] $($K:tt)*) => { - $($K)* - }; - ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => { - <$($K)* as AsLocalKey>::LocalKey - }; - ([$other:tt $($modifiers:tt)*] $($K:tt)*) => { - local_key_if_separate_extern!([$($modifiers)*] $($K)*) - }; -} - -macro_rules! separate_provide_extern_decl { - ([][$name:ident]) => { - () - }; - ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - for<'tcx> fn( - TyCtxt<'tcx>, - query_keys::$name<'tcx>, - ) -> query_provided::$name<'tcx> - }; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - separate_provide_extern_decl!([$($modifiers)*][$($args)*]) - }; -} - -macro_rules! separate_provide_extern_default { - ([][$name:ident]) => { - () - }; - ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - |_, key| bug!( - "`tcx.{}({:?})` unsupported by its crate; \ - perhaps the `{}` query was never assigned a provider function", - stringify!($name), - key, - stringify!($name), - ) - }; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - separate_provide_extern_default!([$($modifiers)*][$($args)*]) - }; -} - -macro_rules! define_callbacks { - ( - $($(#[$attr:meta])* - [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - - // HACK(eddyb) this is like the `impl QueryConfig for queries::$name` - // below, but using type aliases instead of associated types, to bypass - // the limitations around normalizing under HRTB - for example, this: - // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value` - // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`. - // This is primarily used by the `provide!` macro in `rustc_metadata`. - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_keys { - use super::*; - - $(pub type $name<'tcx> = $($K)*;)* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_keys_local { - use super::*; - - $(pub type $name<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);)* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_values { - use super::*; - - $(pub type $name<'tcx> = $V;)* - } - - /// This module specifies the type returned from query providers and the type used for - /// decoding. For regular queries this is the declared returned type `V`, but - /// `arena_cache` will use `<V as Deref>::Target` instead. - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_provided { - use super::*; - - $( - pub type $name<'tcx> = query_if_arena!([$($modifiers)*] (<$V as Deref>::Target) ($V)); - )* - } - - /// This module has a function per query which takes a `query_provided` value and coverts - /// it to a regular `V` value by allocating it on an arena if the query has the - /// `arena_cache` modifier. This will happen when computing the query using a provider or - /// decoding a stored result. - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_provided_to_value { - use super::*; - - $( - #[inline(always)] - pub fn $name<'tcx>( - _tcx: TyCtxt<'tcx>, - value: query_provided::$name<'tcx>, - ) -> Erase<query_values::$name<'tcx>> { - erase(query_if_arena!([$($modifiers)*] - { - if mem::needs_drop::<query_provided::$name<'tcx>>() { - &*_tcx.query_system.arenas.$name.alloc(value) - } else { - &*_tcx.arena.dropless.alloc(value) - } - } - (value) - )) - } - )* - } - #[allow(nonstandard_style, unused_lifetimes)] - pub mod query_storage { - use super::*; - - $( - pub type $name<'tcx> = <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>>>::Cache; - )* - } - - $( - // Ensure that keys grow no larger than 64 bytes - #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] - const _: () = { - if mem::size_of::<query_keys::$name<'static>>() > 64 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a key type `", - stringify!($($K)*), - "` that is too large" - )); - } - }; - - // Ensure that values grow no larger than 64 bytes - #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] - const _: () = { - if mem::size_of::<query_values::$name<'static>>() > 64 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a value type `", - stringify!($V), - "` that is too large" - )); - } - }; - )* - - pub struct QueryArenas<'tcx> { - $($(#[$attr])* pub $name: query_if_arena!([$($modifiers)*] - (WorkerLocal<TypedArena<<$V as Deref>::Target>>) - () - ),)* - } - - impl Default for QueryArenas<'_> { - fn default() -> Self { - Self { - $($name: query_if_arena!([$($modifiers)*] - (WorkerLocal::new(|_| Default::default())) - () - ),)* - } - } - } - - #[derive(Default)] - pub struct QueryCaches<'tcx> { - $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)* - } - - impl<'tcx> TyCtxtEnsure<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - query_ensure( - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - key.into_query_param(), - false, - ); - })* - } - - impl<'tcx> TyCtxtEnsureWithValue<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - query_ensure( - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - key.into_query_param(), - true, - ); - })* - } - - impl<'tcx> TyCtxt<'tcx> { - $($(#[$attr])* - #[inline(always)] - #[must_use] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V - { - self.at(DUMMY_SP).$name(key) - })* - } - - impl<'tcx> TyCtxtAt<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V - { - restore::<$V>(query_get_at( - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - self.span, - key.into_query_param(), - )) - })* - } - - pub struct DynamicQueries<'tcx> { - $( - pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>, - )* - } - - #[derive(Default)] - pub struct QueryStates<'tcx> { - $( - pub $name: QueryState<$($K)*, DepKind>, - )* - } - - pub struct Providers { - $(pub $name: for<'tcx> fn( - TyCtxt<'tcx>, - query_keys_local::$name<'tcx>, - ) -> query_provided::$name<'tcx>,)* - } - - pub struct ExternProviders { - $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)* - } - - impl Default for Providers { - fn default() -> Self { - Providers { - $($name: |_, key| bug!( - "`tcx.{}({:?})` is not supported for this key;\n\ - hint: Queries can be either made to the local crate, or the external crate. \ - This error means you tried to use it for one that's not supported.\n\ - If that's not the case, {} was likely never assigned to a provider function.\n", - stringify!($name), - key, - stringify!($name), - ),)* - } - } - } - - impl Default for ExternProviders { - fn default() -> Self { - ExternProviders { - $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)* - } - } - } - - impl Copy for Providers {} - impl Clone for Providers { - fn clone(&self) -> Self { *self } - } - - impl Copy for ExternProviders {} - impl Clone for ExternProviders { - fn clone(&self) -> Self { *self } - } - - pub struct QueryEngine { - $(pub $name: for<'tcx> fn( - TyCtxt<'tcx>, - Span, - query_keys::$name<'tcx>, - QueryMode, - ) -> Option<Erase<$V>>,)* - } - }; -} - -macro_rules! hash_result { - ([]) => {{ - Some(dep_graph::hash_result) - }}; - ([(no_hash) $($rest:tt)*]) => {{ - None - }}; - ([$other:tt $($modifiers:tt)*]) => { - hash_result!([$($modifiers)*]) - }; -} - -macro_rules! define_feedable { - ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { - $(#[$attr])* - #[inline(always)] - pub fn $name(self, value: query_provided::$name<'tcx>) { - let key = self.key().into_query_param(); - - let tcx = self.tcx; - let erased = query_provided_to_value::$name(tcx, value); - let value = restore::<$V>(erased); - let cache = &tcx.query_system.caches.$name; - - let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]); - match try_get_cached(tcx, cache, &key) { - Some(old) => { - let old = restore::<$V>(old); - if let Some(hasher) = hasher { - let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx| - (hasher(&mut hcx, &value), hasher(&mut hcx, &old)) - ); - assert_eq!( - old_hash, value_hash, - "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", - stringify!($name), - ) - } else { - bug!( - "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", - stringify!($name), - ) - } - } - None => { - let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key); - let dep_node_index = tcx.dep_graph.with_feed_task( - dep_node, - tcx, - key, - &value, - hash_result!([$($modifiers)*]), - ); - cache.complete(key, erased, dep_node_index); - } - } - } - })* - } -} - -// Each of these queries corresponds to a function pointer field in the -// `Providers` struct for requesting a value of that type, and a method -// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way -// which memoizes and does dep-graph tracking, wrapping around the actual -// `Providers` that the driver creates (using several `rustc_*` crates). -// -// The result type of each query must implement `Clone`, and additionally -// `ty::query::values::Value`, which produces an appropriate placeholder -// (error) value if the query resulted in a query cycle. -// Queries marked with `fatal_cycle` do not need the latter implementation, -// as they will raise an fatal error on query cycles instead. - -mod sealed { - use super::{DefId, LocalDefId, OwnerId}; - - /// An analogue of the `Into` trait that's intended only for query parameters. - /// - /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the - /// user call `to_def_id` to convert between them everywhere else. - pub trait IntoQueryParam<P> { - fn into_query_param(self) -> P; - } - - impl<P> IntoQueryParam<P> for P { - #[inline(always)] - fn into_query_param(self) -> P { - self - } - } - - impl<'a, P: Copy> IntoQueryParam<P> for &'a P { - #[inline(always)] - fn into_query_param(self) -> P { - *self - } - } - - impl IntoQueryParam<LocalDefId> for OwnerId { - #[inline(always)] - fn into_query_param(self) -> LocalDefId { - self.def_id - } - } - - impl IntoQueryParam<DefId> for LocalDefId { - #[inline(always)] - fn into_query_param(self) -> DefId { - self.to_def_id() - } - } - - impl IntoQueryParam<DefId> for OwnerId { - #[inline(always)] - fn into_query_param(self) -> DefId { - self.to_def_id() - } - } -} - -pub use sealed::IntoQueryParam; - -impl<'tcx> TyCtxt<'tcx> { - pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind { - let def_id = def_id.into_query_param(); - self.opt_def_kind(def_id) - .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) - } -} - -impl<'tcx> TyCtxtAt<'tcx> { - pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind { - let def_id = def_id.into_query_param(); - self.opt_def_kind(def_id) - .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) - } -} |