2 use crate::infer::canonical::{self, Canonical};
3 use crate::lint::LintExpectation;
4 use crate::metadata::ModChild;
5 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
7 use crate::middle::lib_features::LibFeatures;
8 use crate::middle::privacy::EffectiveVisibilities;
9 use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
10 use crate::middle::stability::{self, DeprecationEntry};
12 use crate::mir::interpret::GlobalId;
13 use crate::mir::interpret::{
14 ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
16 use crate::mir::interpret::{LitToConstError, LitToConstInput};
17 use crate::mir::mono::CodegenUnit;
18 use crate::query::Key;
20 use crate::traits::query::{
21 CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
22 CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
23 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
25 use crate::traits::query::{
26 DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
29 use crate::traits::specialization_graph;
30 use crate::traits::{self, ImplSource};
31 use crate::ty::fast_reject::SimplifiedType;
32 use crate::ty::layout::TyAndLayout;
33 use crate::ty::subst::{GenericArg, SubstsRef};
34 use crate::ty::util::AlwaysRequiresDrop;
35 use crate::ty::GeneratorDiagnosticData;
36 use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
38 use rustc_ast::expand::allocator::AllocatorKind;
39 use rustc_attr as attr;
40 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
41 use rustc_data_structures::steal::Steal;
42 use rustc_data_structures::svh::Svh;
43 use rustc_data_structures::sync::Lrc;
44 use rustc_data_structures::unord::UnordSet;
45 use rustc_errors::ErrorGuaranteed;
47 use rustc_hir::def::DefKind;
48 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
49 use rustc_hir::hir_id::OwnerId;
50 use rustc_hir::lang_items::{LangItem, LanguageItems};
51 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
52 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
53 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
54 use rustc_session::cstore::{CrateDepKind, CrateSource};
55 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
56 use rustc_session::lint::LintExpectationId;
57 use rustc_session::Limits;
58 use rustc_span::symbol::Symbol;
59 use rustc_span::{Span, DUMMY_SP};
60 use rustc_target::abi;
61 use rustc_target::spec::PanicStrategy;
63 use std::path::PathBuf;
66 pub(crate) use rustc_query_system::query::QueryJobId;
67 use rustc_query_system::query::*;
69 #[derive(Copy, Clone)]
70 pub struct TyCtxtAt<'tcx> {
71 pub tcx: TyCtxt<'tcx>,
75 impl<'tcx> 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>,
88 impl<'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 /// Helper for `TyCtxtEnsure` to avoid a closure.
112 /// Helper to ensure that queries only return `Copy` types.
114 fn copy<T: Copy>(x: &T) -> T {
118 macro_rules! query_helper_param_ty {
119 (DefId) => { impl IntoQueryParam<DefId> };
123 macro_rules! query_storage {
124 ([][$K:ty, $V:ty]) => {
125 <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache
127 ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
128 <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::ArenaCache
130 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
131 query_storage!([$($modifiers)*][$($args)*])
135 macro_rules! separate_provide_extern_decl {
136 ([][$name:ident]) => {
139 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
142 query_keys::$name<'tcx>,
143 ) -> query_values::$name<'tcx>
145 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
146 separate_provide_extern_decl!([$($modifiers)*][$($args)*])
150 macro_rules! separate_provide_extern_default {
151 ([][$name:ident]) => {
154 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
156 "`tcx.{}({:?})` unsupported by its crate; \
157 perhaps the `{}` query was never assigned a provider function",
163 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
164 separate_provide_extern_default!([$($modifiers)*][$($args)*])
168 macro_rules! opt_remap_env_constness {
169 ([][$name:ident]) => {};
170 ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
171 let $name = $name.without_const();
173 ([$other:tt $($modifiers:tt)*][$name:ident]) => {
174 opt_remap_env_constness!([$($modifiers)*][$name])
178 macro_rules! define_callbacks {
181 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
183 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
184 // below, but using type aliases instead of associated types, to bypass
185 // the limitations around normalizing under HRTB - for example, this:
186 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
187 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
188 // This is primarily used by the `provide!` macro in `rustc_metadata`.
189 #[allow(nonstandard_style, unused_lifetimes)]
193 $(pub type $name<'tcx> = $($K)*;)*
195 #[allow(nonstandard_style, unused_lifetimes)]
196 pub mod query_values {
199 $(pub type $name<'tcx> = $V;)*
201 #[allow(nonstandard_style, unused_lifetimes)]
202 pub mod query_storage {
205 $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
207 #[allow(nonstandard_style, unused_lifetimes)]
208 pub mod query_stored {
211 $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
215 pub struct QueryCaches<'tcx> {
216 $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
219 impl<'tcx> TyCtxtEnsure<'tcx> {
222 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
223 let key = key.into_query_param();
224 opt_remap_env_constness!([$($modifiers)*][key]);
226 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
233 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
237 impl<'tcx> TyCtxt<'tcx> {
241 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
243 self.at(DUMMY_SP).$name(key)
247 impl<'tcx> TyCtxtAt<'tcx> {
250 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
252 let key = key.into_query_param();
253 opt_remap_env_constness!([$($modifiers)*][key]);
255 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
258 Ok(value) => return value,
262 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
266 pub struct Providers {
267 $(pub $name: for<'tcx> fn(
269 query_keys::$name<'tcx>,
270 ) -> query_values::$name<'tcx>,)*
273 pub struct ExternProviders {
274 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
277 impl Default for Providers {
278 fn default() -> Self {
279 use crate::query::Key;
282 $($name: |_, key| bug!(
283 "`tcx.{}({:?})` is not supported for {} crate;\n
284 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
285 If that's not the case, {} was likely never assigned to a provider function.\n",
288 if key.query_crate_is_local() { "local" } else { "external" },
295 impl Default for ExternProviders {
296 fn default() -> Self {
298 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
303 impl Copy for Providers {}
304 impl Clone for Providers {
305 fn clone(&self) -> Self { *self }
308 impl Copy for ExternProviders {}
309 impl Clone for ExternProviders {
310 fn clone(&self) -> Self { *self }
313 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
314 fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
316 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
323 key: query_keys::$name<'tcx>,
325 ) -> Option<query_stored::$name<'tcx>>;)*
330 // Each of these queries corresponds to a function pointer field in the
331 // `Providers` struct for requesting a value of that type, and a method
332 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
333 // which memoizes and does dep-graph tracking, wrapping around the actual
334 // `Providers` that the driver creates (using several `rustc_*` crates).
336 // The result type of each query must implement `Clone`, and additionally
337 // `ty::query::values::Value`, which produces an appropriate placeholder
338 // (error) value if the query resulted in a query cycle.
339 // Queries marked with `fatal_cycle` do not need the latter implementation,
340 // as they will raise an fatal error on query cycles instead.
342 rustc_query_append! { define_callbacks! }
345 use super::{DefId, LocalDefId, OwnerId};
347 /// An analogue of the `Into` trait that's intended only for query parameters.
349 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
350 /// user call `to_def_id` to convert between them everywhere else.
351 pub trait IntoQueryParam<P> {
352 fn into_query_param(self) -> P;
355 impl<P> IntoQueryParam<P> for P {
357 fn into_query_param(self) -> P {
362 impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
364 fn into_query_param(self) -> P {
369 impl IntoQueryParam<DefId> for LocalDefId {
371 fn into_query_param(self) -> DefId {
376 impl IntoQueryParam<DefId> for OwnerId {
378 fn into_query_param(self) -> DefId {
384 use sealed::IntoQueryParam;
386 impl<'tcx> TyCtxt<'tcx> {
387 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
388 let def_id = def_id.into_query_param();
389 self.opt_def_kind(def_id)
390 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
394 impl<'tcx> TyCtxtAt<'tcx> {
395 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
396 let def_id = def_id.into_query_param();
397 self.opt_def_kind(def_id)
398 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))