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::AccessLevels;
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;
19 use crate::traits::query::{
20 CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
21 CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
22 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
24 use crate::traits::query::{
25 DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
28 use crate::traits::specialization_graph;
29 use crate::traits::{self, ImplSource};
30 use crate::ty::fast_reject::SimplifiedType;
31 use crate::ty::layout::TyAndLayout;
32 use crate::ty::subst::{GenericArg, SubstsRef};
33 use crate::ty::util::AlwaysRequiresDrop;
34 use crate::ty::GeneratorDiagnosticData;
35 use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
37 use rustc_ast::expand::allocator::AllocatorKind;
38 use rustc_attr as attr;
39 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
40 use rustc_data_structures::steal::Steal;
41 use rustc_data_structures::svh::Svh;
42 use rustc_data_structures::sync::Lrc;
43 use rustc_errors::ErrorGuaranteed;
45 use rustc_hir::def::DefKind;
46 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
47 use rustc_hir::hir_id::OwnerId;
48 use rustc_hir::lang_items::{LangItem, LanguageItems};
49 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
50 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
51 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
52 use rustc_session::cstore::{CrateDepKind, CrateSource};
53 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
54 use rustc_session::lint::LintExpectationId;
55 use rustc_session::Limits;
56 use rustc_span::symbol::Symbol;
57 use rustc_span::{Span, DUMMY_SP};
58 use rustc_target::abi;
59 use rustc_target::spec::PanicStrategy;
61 use std::path::PathBuf;
64 pub(crate) use rustc_query_system::query::QueryJobId;
65 use rustc_query_system::query::*;
67 #[derive(Copy, Clone)]
68 pub struct TyCtxtAt<'tcx> {
69 pub tcx: TyCtxt<'tcx>,
73 impl<'tcx> Deref for TyCtxtAt<'tcx> {
74 type Target = TyCtxt<'tcx>;
76 fn deref(&self) -> &Self::Target {
81 #[derive(Copy, Clone)]
82 pub struct TyCtxtEnsure<'tcx> {
83 pub tcx: TyCtxt<'tcx>,
86 impl<'tcx> TyCtxt<'tcx> {
87 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
88 /// are executed instead of just returning their results.
90 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
91 TyCtxtEnsure { tcx: self }
94 /// Returns a transparent wrapper for `TyCtxt` which uses
95 /// `span` as the location of queries performed through it.
97 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
98 TyCtxtAt { tcx: self, span }
101 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
102 self.queries.try_mark_green(self, dep_node)
106 /// Helper for `TyCtxtEnsure` to avoid a closure.
110 /// Helper to ensure that queries only return `Copy` types.
112 fn copy<T: Copy>(x: &T) -> T {
116 macro_rules! query_helper_param_ty {
117 (DefId) => { impl IntoQueryParam<DefId> };
121 macro_rules! query_storage {
122 ([][$K:ty, $V:ty]) => {
123 <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
125 ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
126 <ArenaCacheSelector<'tcx> as CacheSelector<$K, $V>>::Cache
128 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
129 query_storage!([$($modifiers)*][$($args)*])
133 macro_rules! separate_provide_extern_decl {
134 ([][$name:ident]) => {
137 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
140 query_keys::$name<'tcx>,
141 ) -> query_values::$name<'tcx>
143 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
144 separate_provide_extern_decl!([$($modifiers)*][$($args)*])
148 macro_rules! separate_provide_extern_default {
149 ([][$name:ident]) => {
152 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
154 "`tcx.{}({:?})` unsupported by its crate; \
155 perhaps the `{}` query was never assigned a provider function",
161 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
162 separate_provide_extern_default!([$($modifiers)*][$($args)*])
166 macro_rules! opt_remap_env_constness {
167 ([][$name:ident]) => {};
168 ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
169 let $name = $name.without_const();
171 ([$other:tt $($modifiers:tt)*][$name:ident]) => {
172 opt_remap_env_constness!([$($modifiers)*][$name])
176 macro_rules! define_callbacks {
179 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
181 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
182 // below, but using type aliases instead of associated types, to bypass
183 // the limitations around normalizing under HRTB - for example, this:
184 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
185 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
186 // This is primarily used by the `provide!` macro in `rustc_metadata`.
187 #[allow(nonstandard_style, unused_lifetimes)]
191 $(pub type $name<'tcx> = $($K)*;)*
193 #[allow(nonstandard_style, unused_lifetimes)]
194 pub mod query_values {
197 $(pub type $name<'tcx> = $V;)*
199 #[allow(nonstandard_style, unused_lifetimes)]
200 pub mod query_storage {
203 $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
205 #[allow(nonstandard_style, unused_lifetimes)]
206 pub mod query_stored {
209 $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
213 pub struct QueryCaches<'tcx> {
214 $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
217 impl<'tcx> TyCtxtEnsure<'tcx> {
220 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
221 let key = key.into_query_param();
222 opt_remap_env_constness!([$($modifiers)*][key]);
224 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
231 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
235 impl<'tcx> TyCtxt<'tcx> {
239 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
241 self.at(DUMMY_SP).$name(key)
245 impl<'tcx> TyCtxtAt<'tcx> {
248 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
250 let key = key.into_query_param();
251 opt_remap_env_constness!([$($modifiers)*][key]);
253 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
256 Ok(value) => return value,
260 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
264 pub struct Providers {
265 $(pub $name: for<'tcx> fn(
267 query_keys::$name<'tcx>,
268 ) -> query_values::$name<'tcx>,)*
271 pub struct ExternProviders {
272 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
275 impl Default for Providers {
276 fn default() -> Self {
278 $($name: |_, key| bug!(
279 "`tcx.{}({:?})` is not supported for external or local crate;\n
280 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 (likely the local crate).\n
281 If that's not the case, {} was likely never assigned to a provider function.\n",
290 impl Default for ExternProviders {
291 fn default() -> Self {
293 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
298 impl Copy for Providers {}
299 impl Clone for Providers {
300 fn clone(&self) -> Self { *self }
303 impl Copy for ExternProviders {}
304 impl Clone for ExternProviders {
305 fn clone(&self) -> Self { *self }
308 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
309 fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
311 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
318 key: query_keys::$name<'tcx>,
320 ) -> Option<query_stored::$name<'tcx>>;)*
325 // Each of these queries corresponds to a function pointer field in the
326 // `Providers` struct for requesting a value of that type, and a method
327 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
328 // which memoizes and does dep-graph tracking, wrapping around the actual
329 // `Providers` that the driver creates (using several `rustc_*` crates).
331 // The result type of each query must implement `Clone`, and additionally
332 // `ty::query::values::Value`, which produces an appropriate placeholder
333 // (error) value if the query resulted in a query cycle.
334 // Queries marked with `fatal_cycle` do not need the latter implementation,
335 // as they will raise an fatal error on query cycles instead.
337 rustc_query_append! { define_callbacks! }
340 use super::{DefId, LocalDefId, OwnerId};
342 /// An analogue of the `Into` trait that's intended only for query parameters.
344 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
345 /// user call `to_def_id` to convert between them everywhere else.
346 pub trait IntoQueryParam<P> {
347 fn into_query_param(self) -> P;
350 impl<P> IntoQueryParam<P> for P {
352 fn into_query_param(self) -> P {
357 impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
359 fn into_query_param(self) -> P {
364 impl IntoQueryParam<DefId> for LocalDefId {
366 fn into_query_param(self) -> DefId {
371 impl IntoQueryParam<DefId> for OwnerId {
373 fn into_query_param(self) -> DefId {
379 use sealed::IntoQueryParam;
381 impl<'tcx> TyCtxt<'tcx> {
382 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
383 let def_id = def_id.into_query_param();
384 self.opt_def_kind(def_id)
385 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
389 impl<'tcx> TyCtxtAt<'tcx> {
390 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
391 let def_id = def_id.into_query_param();
392 self.opt_def_kind(def_id)
393 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))