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;
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_data_structures::unord::UnordSet;
44 use rustc_errors::ErrorGuaranteed;
46 use rustc_hir::def::DefKind;
47 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
48 use rustc_hir::hir_id::OwnerId;
49 use rustc_hir::lang_items::{LangItem, LanguageItems};
50 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
51 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
52 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
53 use rustc_session::cstore::{CrateDepKind, CrateSource};
54 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
55 use rustc_session::lint::LintExpectationId;
56 use rustc_session::Limits;
57 use rustc_span::symbol::Symbol;
58 use rustc_span::{Span, DUMMY_SP};
59 use rustc_target::abi;
60 use rustc_target::spec::PanicStrategy;
62 use std::path::PathBuf;
65 pub(crate) use rustc_query_system::query::QueryJobId;
66 use rustc_query_system::query::*;
68 #[derive(Copy, Clone)]
69 pub struct TyCtxtAt<'tcx> {
70 pub tcx: TyCtxt<'tcx>,
74 impl<'tcx> Deref for TyCtxtAt<'tcx> {
75 type Target = TyCtxt<'tcx>;
77 fn deref(&self) -> &Self::Target {
82 #[derive(Copy, Clone)]
83 pub struct TyCtxtEnsure<'tcx> {
84 pub tcx: TyCtxt<'tcx>,
87 impl<'tcx> TyCtxt<'tcx> {
88 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
89 /// are executed instead of just returning their results.
91 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
92 TyCtxtEnsure { tcx: self }
95 /// Returns a transparent wrapper for `TyCtxt` which uses
96 /// `span` as the location of queries performed through it.
98 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
99 TyCtxtAt { tcx: self, span }
102 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
103 self.queries.try_mark_green(self, dep_node)
107 /// Helper for `TyCtxtEnsure` to avoid a closure.
111 /// Helper to ensure that queries only return `Copy` types.
113 fn copy<T: Copy>(x: &T) -> T {
117 macro_rules! query_helper_param_ty {
118 (DefId) => { impl IntoQueryParam<DefId> };
122 macro_rules! query_storage {
123 ([][$K:ty, $V:ty]) => {
124 <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
126 ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
127 <ArenaCacheSelector<'tcx> as CacheSelector<$K, $V>>::Cache
129 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
130 query_storage!([$($modifiers)*][$($args)*])
134 macro_rules! separate_provide_extern_decl {
135 ([][$name:ident]) => {
138 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
141 query_keys::$name<'tcx>,
142 ) -> query_values::$name<'tcx>
144 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
145 separate_provide_extern_decl!([$($modifiers)*][$($args)*])
149 macro_rules! separate_provide_extern_default {
150 ([][$name:ident]) => {
153 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
155 "`tcx.{}({:?})` unsupported by its crate; \
156 perhaps the `{}` query was never assigned a provider function",
162 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
163 separate_provide_extern_default!([$($modifiers)*][$($args)*])
167 macro_rules! opt_remap_env_constness {
168 ([][$name:ident]) => {};
169 ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
170 let $name = $name.without_const();
172 ([$other:tt $($modifiers:tt)*][$name:ident]) => {
173 opt_remap_env_constness!([$($modifiers)*][$name])
177 macro_rules! define_callbacks {
180 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
182 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
183 // below, but using type aliases instead of associated types, to bypass
184 // the limitations around normalizing under HRTB - for example, this:
185 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
186 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
187 // This is primarily used by the `provide!` macro in `rustc_metadata`.
188 #[allow(nonstandard_style, unused_lifetimes)]
192 $(pub type $name<'tcx> = $($K)*;)*
194 #[allow(nonstandard_style, unused_lifetimes)]
195 pub mod query_values {
198 $(pub type $name<'tcx> = $V;)*
200 #[allow(nonstandard_style, unused_lifetimes)]
201 pub mod query_storage {
204 $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
206 #[allow(nonstandard_style, unused_lifetimes)]
207 pub mod query_stored {
210 $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
214 pub struct QueryCaches<'tcx> {
215 $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
218 impl<'tcx> TyCtxtEnsure<'tcx> {
221 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
222 let key = key.into_query_param();
223 opt_remap_env_constness!([$($modifiers)*][key]);
225 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
232 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
236 impl<'tcx> TyCtxt<'tcx> {
240 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
242 self.at(DUMMY_SP).$name(key)
246 impl<'tcx> TyCtxtAt<'tcx> {
249 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
251 let key = key.into_query_param();
252 opt_remap_env_constness!([$($modifiers)*][key]);
254 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
257 Ok(value) => return value,
261 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
265 pub struct Providers {
266 $(pub $name: for<'tcx> fn(
268 query_keys::$name<'tcx>,
269 ) -> query_values::$name<'tcx>,)*
272 pub struct ExternProviders {
273 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
276 impl Default for Providers {
277 fn default() -> Self {
279 $($name: |_, key| bug!(
280 "`tcx.{}({:?})` is not supported for external or local crate;\n
281 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
282 If that's not the case, {} was likely never assigned to a provider function.\n",
291 impl Default for ExternProviders {
292 fn default() -> Self {
294 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
299 impl Copy for Providers {}
300 impl Clone for Providers {
301 fn clone(&self) -> Self { *self }
304 impl Copy for ExternProviders {}
305 impl Clone for ExternProviders {
306 fn clone(&self) -> Self { *self }
309 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
310 fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
312 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
319 key: query_keys::$name<'tcx>,
321 ) -> Option<query_stored::$name<'tcx>>;)*
326 // Each of these queries corresponds to a function pointer field in the
327 // `Providers` struct for requesting a value of that type, and a method
328 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
329 // which memoizes and does dep-graph tracking, wrapping around the actual
330 // `Providers` that the driver creates (using several `rustc_*` crates).
332 // The result type of each query must implement `Clone`, and additionally
333 // `ty::query::values::Value`, which produces an appropriate placeholder
334 // (error) value if the query resulted in a query cycle.
335 // Queries marked with `fatal_cycle` do not need the latter implementation,
336 // as they will raise an fatal error on query cycles instead.
338 rustc_query_append! { define_callbacks! }
341 use super::{DefId, LocalDefId, OwnerId};
343 /// An analogue of the `Into` trait that's intended only for query parameters.
345 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
346 /// user call `to_def_id` to convert between them everywhere else.
347 pub trait IntoQueryParam<P> {
348 fn into_query_param(self) -> P;
351 impl<P> IntoQueryParam<P> for P {
353 fn into_query_param(self) -> P {
358 impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
360 fn into_query_param(self) -> P {
365 impl IntoQueryParam<DefId> for LocalDefId {
367 fn into_query_param(self) -> DefId {
372 impl IntoQueryParam<DefId> for OwnerId {
374 fn into_query_param(self) -> DefId {
380 use sealed::IntoQueryParam;
382 impl<'tcx> TyCtxt<'tcx> {
383 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
384 let def_id = def_id.into_query_param();
385 self.opt_def_kind(def_id)
386 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
390 impl<'tcx> TyCtxtAt<'tcx> {
391 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
392 let def_id = def_id.into_query_param();
393 self.opt_def_kind(def_id)
394 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))