2 use crate::infer::canonical::{self, Canonical};
3 use crate::lint::LintLevelMap;
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::subst::{GenericArg, SubstsRef};
32 use crate::ty::util::AlwaysRequiresDrop;
33 use crate::ty::GeneratorDiagnosticData;
34 use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
36 use rustc_ast::expand::allocator::AllocatorKind;
37 use rustc_attr as attr;
38 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
39 use rustc_data_structures::steal::Steal;
40 use rustc_data_structures::svh::Svh;
41 use rustc_data_structures::sync::Lrc;
42 use rustc_errors::ErrorGuaranteed;
44 use rustc_hir::def::DefKind;
45 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
46 use rustc_hir::lang_items::{LangItem, LanguageItems};
47 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
48 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
49 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
50 use rustc_session::cstore::{CrateDepKind, CrateSource};
51 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
52 use rustc_session::utils::NativeLibKind;
53 use rustc_session::Limits;
54 use rustc_span::symbol::Symbol;
55 use rustc_span::{Span, DUMMY_SP};
56 use rustc_target::abi;
57 use rustc_target::spec::PanicStrategy;
59 use std::path::PathBuf;
62 pub(crate) use rustc_query_system::query::QueryJobId;
63 use rustc_query_system::query::*;
65 #[derive(Copy, Clone)]
66 pub struct TyCtxtAt<'tcx> {
67 pub tcx: TyCtxt<'tcx>,
71 impl<'tcx> Deref for TyCtxtAt<'tcx> {
72 type Target = TyCtxt<'tcx>;
74 fn deref(&self) -> &Self::Target {
79 #[derive(Copy, Clone)]
80 pub struct TyCtxtEnsure<'tcx> {
81 pub tcx: TyCtxt<'tcx>,
84 impl<'tcx> TyCtxt<'tcx> {
85 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
86 /// are executed instead of just returning their results.
88 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
89 TyCtxtEnsure { tcx: self }
92 /// Returns a transparent wrapper for `TyCtxt` which uses
93 /// `span` as the location of queries performed through it.
95 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
96 TyCtxtAt { tcx: self, span }
99 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
100 self.queries.try_mark_green(self, dep_node)
104 /// Helper for `TyCtxtEnsure` to avoid a closure.
108 /// Helper to ensure that queries only return `Copy` types.
110 fn copy<T: Copy>(x: &T) -> T {
114 macro_rules! query_helper_param_ty {
115 (DefId) => { impl IntoQueryParam<DefId> };
119 macro_rules! query_storage {
120 ([][$K:ty, $V:ty]) => {
121 <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
123 ([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
124 <$ty as CacheSelector<$K, $V>>::Cache
126 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
127 query_storage!([$($modifiers)*][$($args)*])
131 macro_rules! separate_provide_extern_decl {
132 ([][$name:ident]) => {
135 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
138 query_keys::$name<'tcx>,
139 ) -> query_values::$name<'tcx>
141 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
142 separate_provide_extern_decl!([$($modifiers)*][$($args)*])
146 macro_rules! separate_provide_extern_default {
147 ([][$name:ident]) => {
150 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
152 "`tcx.{}({:?})` unsupported by its crate; \
153 perhaps the `{}` query was never assigned a provider function",
159 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
160 separate_provide_extern_default!([$($modifiers)*][$($args)*])
164 macro_rules! opt_remap_env_constness {
165 ([][$name:ident]) => {};
166 ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
167 let $name = $name.without_const();
169 ([$other:tt $($modifiers:tt)*][$name:ident]) => {
170 opt_remap_env_constness!([$($modifiers)*][$name])
174 macro_rules! define_callbacks {
177 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
179 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
180 // below, but using type aliases instead of associated types, to bypass
181 // the limitations around normalizing under HRTB - for example, this:
182 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
183 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
184 // This is primarily used by the `provide!` macro in `rustc_metadata`.
185 #[allow(nonstandard_style, unused_lifetimes)]
189 $(pub type $name<$tcx> = $($K)*;)*
191 #[allow(nonstandard_style, unused_lifetimes)]
192 pub mod query_values {
195 $(pub type $name<$tcx> = $V;)*
197 #[allow(nonstandard_style, unused_lifetimes)]
198 pub mod query_storage {
201 $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
203 #[allow(nonstandard_style, unused_lifetimes)]
204 pub mod query_stored {
207 $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
211 pub struct QueryCaches<$tcx> {
212 $($(#[$attr])* pub $name: query_storage::$name<$tcx>,)*
215 impl<$tcx> TyCtxtEnsure<$tcx> {
218 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
219 let key = key.into_query_param();
220 opt_remap_env_constness!([$($modifiers)*][key]);
222 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
229 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
233 impl<$tcx> TyCtxt<$tcx> {
237 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
239 self.at(DUMMY_SP).$name(key)
243 impl<$tcx> TyCtxtAt<$tcx> {
246 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
248 let key = key.into_query_param();
249 opt_remap_env_constness!([$($modifiers)*][key]);
251 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
254 Ok(value) => return value,
258 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
262 pub struct Providers {
263 $(pub $name: for<'tcx> fn(
265 query_keys::$name<'tcx>,
266 ) -> query_values::$name<'tcx>,)*
269 pub struct ExternProviders {
270 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
273 impl Default for Providers {
274 fn default() -> Self {
276 $($name: |_, key| bug!(
277 "`tcx.{}({:?})` unsupported by its crate; \
278 perhaps the `{}` query was never assigned a provider function",
287 impl Default for ExternProviders {
288 fn default() -> Self {
290 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
295 impl Copy for Providers {}
296 impl Clone for Providers {
297 fn clone(&self) -> Self { *self }
300 impl Copy for ExternProviders {}
301 impl Clone for ExternProviders {
302 fn clone(&self) -> Self { *self }
305 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
306 fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
308 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
315 key: query_keys::$name<$tcx>,
317 ) -> Option<query_stored::$name<$tcx>>;)*
322 // Each of these queries corresponds to a function pointer field in the
323 // `Providers` struct for requesting a value of that type, and a method
324 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
325 // which memoizes and does dep-graph tracking, wrapping around the actual
326 // `Providers` that the driver creates (using several `rustc_*` crates).
328 // The result type of each query must implement `Clone`, and additionally
329 // `ty::query::values::Value`, which produces an appropriate placeholder
330 // (error) value if the query resulted in a query cycle.
331 // Queries marked with `fatal_cycle` do not need the latter implementation,
332 // as they will raise an fatal error on query cycles instead.
334 rustc_query_append! { [define_callbacks!][<'tcx>] }
337 use super::{DefId, LocalDefId};
339 /// An analogue of the `Into` trait that's intended only for query parameters.
341 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
342 /// user call `to_def_id` to convert between them everywhere else.
343 pub trait IntoQueryParam<P> {
344 fn into_query_param(self) -> P;
347 impl<P> IntoQueryParam<P> for P {
349 fn into_query_param(self) -> P {
354 impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
356 fn into_query_param(self) -> P {
361 impl IntoQueryParam<DefId> for LocalDefId {
363 fn into_query_param(self) -> DefId {
369 use sealed::IntoQueryParam;
371 impl<'tcx> TyCtxt<'tcx> {
372 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
373 let def_id = def_id.into_query_param();
374 self.opt_def_kind(def_id)
375 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
379 impl<'tcx> TyCtxtAt<'tcx> {
380 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
381 let def_id = def_id.into_query_param();
382 self.opt_def_kind(def_id)
383 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))