2 use crate::hir::exports::Export;
3 use crate::infer::canonical::{self, Canonical};
4 use crate::lint::LintLevelMap;
5 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6 use crate::middle::cstore::{CrateDepKind, CrateSource};
7 use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
8 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
9 use crate::middle::lib_features::LibFeatures;
10 use crate::middle::privacy::AccessLevels;
11 use crate::middle::region;
12 use crate::middle::resolve_lifetime::{
13 LifetimeScopeForPath, ObjectLifetimeDefault, Region, ResolveLifetimes,
15 use crate::middle::stability::{self, DeprecationEntry};
17 use crate::mir::interpret::GlobalId;
18 use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput};
19 use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult};
20 use crate::mir::mono::CodegenUnit;
22 use crate::traits::query::{
23 CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
24 CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
25 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
27 use crate::traits::query::{
28 DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
31 use crate::traits::specialization_graph;
32 use crate::traits::{self, ImplSource};
33 use crate::ty::subst::{GenericArg, SubstsRef};
34 use crate::ty::util::AlwaysRequiresDrop;
35 use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
36 use rustc_ast::expand::allocator::AllocatorKind;
37 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
38 use rustc_data_structures::steal::Steal;
39 use rustc_data_structures::svh::Svh;
40 use rustc_data_structures::sync::Lrc;
41 use rustc_errors::{ErrorReported, Handler};
43 use rustc_hir::def::DefKind;
44 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
45 use rustc_hir::lang_items::{LangItem, LanguageItems};
46 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
47 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
48 use rustc_serialize::opaque;
49 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
50 use rustc_session::utils::NativeLibKind;
51 use rustc_session::CrateDisambiguator;
52 use rustc_target::spec::PanicStrategy;
55 use rustc_attr as attr;
56 use rustc_span::symbol::Symbol;
57 use rustc_span::{Span, DUMMY_SP};
58 use std::collections::BTreeMap;
60 use std::path::PathBuf;
63 pub(crate) use rustc_query_system::query::QueryJobId;
64 use rustc_query_system::query::*;
66 pub mod on_disk_cache;
67 pub use self::on_disk_cache::OnDiskCache;
69 #[derive(Copy, Clone)]
70 pub struct TyCtxtAt<'tcx> {
71 pub tcx: TyCtxt<'tcx>,
75 impl Deref for TyCtxtAt<'tcx> {
76 type Target = TyCtxt<'tcx>;
78 fn deref(&self) -> &Self::Target {
83 #[derive(Copy, Clone)]
84 pub struct TyCtxtEnsure<'tcx> {
85 pub tcx: TyCtxt<'tcx>,
89 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
90 /// are executed instead of just returning their results.
92 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
93 TyCtxtEnsure { tcx: self }
96 /// Returns a transparent wrapper for `TyCtxt` which uses
97 /// `span` as the location of queries performed through it.
99 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
100 TyCtxtAt { tcx: self, span }
103 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
104 self.queries.try_mark_green(self, dep_node)
108 macro_rules! query_helper_param_ty {
109 (DefId) => { impl IntoQueryParam<DefId> };
113 macro_rules! query_storage {
114 ([][$K:ty, $V:ty]) => {
115 <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
117 ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
118 <$ty as CacheSelector<$K, $V>>::Cache
120 ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
121 query_storage!([$($($modifiers)*)*][$($args)*])
125 macro_rules! define_callbacks {
128 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
130 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
131 // below, but using type aliases instead of associated types, to bypass
132 // the limitations around normalizing under HRTB - for example, this:
133 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
134 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
135 // This is primarily used by the `provide!` macro in `rustc_metadata`.
136 #[allow(nonstandard_style, unused_lifetimes)]
140 $(pub type $name<$tcx> = $($K)*;)*
142 #[allow(nonstandard_style, unused_lifetimes)]
143 pub mod query_values {
146 $(pub type $name<$tcx> = $V;)*
148 #[allow(nonstandard_style, unused_lifetimes)]
149 pub mod query_storage {
152 $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
154 #[allow(nonstandard_style, unused_lifetimes)]
155 pub mod query_stored {
158 $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
162 pub struct QueryCaches<$tcx> {
163 $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
166 impl TyCtxtEnsure<$tcx> {
169 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
170 let key = key.into_query_param();
171 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {});
173 let lookup = match cached {
175 Err(lookup) => lookup,
178 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
186 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
188 self.at(DUMMY_SP).$name(key)
192 impl TyCtxtAt<$tcx> {
195 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
197 let key = key.into_query_param();
198 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| {
202 let lookup = match cached {
203 Ok(value) => return value,
204 Err(lookup) => lookup,
207 self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
211 pub struct Providers {
212 $(pub $name: for<'tcx> fn(
214 query_keys::$name<'tcx>,
215 ) -> query_values::$name<'tcx>,)*
218 impl Default for Providers {
219 fn default() -> Self {
221 $($name: |_, key| bug!(
222 "`tcx.{}({:?})` unsupported by its crate; \
223 perhaps the `{}` query was never assigned a provider function",
232 impl Copy for Providers {}
233 impl Clone for Providers {
234 fn clone(&self) -> Self { *self }
237 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
238 #[cfg(parallel_compiler)]
239 unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry);
241 fn encode_query_results(
244 encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
245 query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
246 ) -> opaque::FileEncodeResult;
248 fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>);
250 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
252 fn try_print_query_stack(
255 query: Option<QueryJobId<dep_graph::DepKind>>,
257 num_frames: Option<usize>,
265 key: query_keys::$name<$tcx>,
268 ) -> Option<query_stored::$name<$tcx>>;)*
273 // Each of these queries corresponds to a function pointer field in the
274 // `Providers` struct for requesting a value of that type, and a method
275 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
276 // which memoizes and does dep-graph tracking, wrapping around the actual
277 // `Providers` that the driver creates (using several `rustc_*` crates).
279 // The result type of each query must implement `Clone`, and additionally
280 // `ty::query::values::Value`, which produces an appropriate placeholder
281 // (error) value if the query resulted in a query cycle.
282 // Queries marked with `fatal_cycle` do not need the latter implementation,
283 // as they will raise an fatal error on query cycles instead.
285 rustc_query_append! { [define_callbacks!][<'tcx>] }
288 use super::{DefId, LocalDefId};
290 /// An analogue of the `Into` trait that's intended only for query paramaters.
292 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
293 /// user call `to_def_id` to convert between them everywhere else.
294 pub trait IntoQueryParam<P> {
295 fn into_query_param(self) -> P;
298 impl<P> IntoQueryParam<P> for P {
300 fn into_query_param(self) -> P {
305 impl IntoQueryParam<DefId> for LocalDefId {
307 fn into_query_param(self) -> DefId {
313 use sealed::IntoQueryParam;
316 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
317 let def_id = def_id.into_query_param();
318 self.opt_def_kind(def_id)
319 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
323 impl TyCtxtAt<'tcx> {
324 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
325 let def_id = def_id.into_query_param();
326 self.opt_def_kind(def_id)
327 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))