summaryrefslogtreecommitdiff
path: root/compiler/rustc_middle/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty')
-rw-r--r--compiler/rustc_middle/src/ty/context.rs8
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs9
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/query.rs640
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))
- }
-}