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::context::TyCtxtFeed;
32 use crate::ty::fast_reject::SimplifiedType;
33 use crate::ty::layout::TyAndLayout;
34 use crate::ty::subst::{GenericArg, SubstsRef};
35 use crate::ty::util::AlwaysRequiresDrop;
36 use crate::ty::GeneratorDiagnosticData;
37 use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
39 use rustc_ast::expand::allocator::AllocatorKind;
40 use rustc_attr as attr;
41 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
42 use rustc_data_structures::steal::Steal;
43 use rustc_data_structures::svh::Svh;
44 use rustc_data_structures::sync::Lrc;
45 use rustc_data_structures::unord::UnordSet;
46 use rustc_errors::ErrorGuaranteed;
48 use rustc_hir::def::DefKind;
49 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
50 use rustc_hir::hir_id::OwnerId;
51 use rustc_hir::lang_items::{LangItem, LanguageItems};
52 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
53 use rustc_index::vec::IndexVec;
54 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
55 use rustc_session::cstore::{CrateDepKind, CrateSource};
56 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
57 use rustc_session::lint::LintExpectationId;
58 use rustc_session::Limits;
59 use rustc_span::symbol::Symbol;
60 use rustc_span::{Span, DUMMY_SP};
61 use rustc_target::abi;
62 use rustc_target::spec::PanicStrategy;
64 use std::path::PathBuf;
67 pub(crate) use rustc_query_system::query::QueryJobId;
68 use rustc_query_system::query::*;
70 #[derive(Copy, Clone)]
71 pub struct TyCtxtAt<'tcx> {
72 pub tcx: TyCtxt<'tcx>,
76 impl<'tcx> Deref for TyCtxtAt<'tcx> {
77 type Target = TyCtxt<'tcx>;
79 fn deref(&self) -> &Self::Target {
84 #[derive(Copy, Clone)]
85 pub struct TyCtxtEnsure<'tcx> {
86 pub tcx: TyCtxt<'tcx>,
89 impl<'tcx> TyCtxt<'tcx> {
90 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
91 /// are executed instead of just returning their results.
93 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
94 TyCtxtEnsure { tcx: self }
97 /// Returns a transparent wrapper for `TyCtxt` which uses
98 /// `span` as the location of queries performed through it.
100 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
101 TyCtxtAt { tcx: self, span }
104 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
105 self.queries.try_mark_green(self, dep_node)
109 /// Helper for `TyCtxtEnsure` to avoid a closure.
113 /// Helper to ensure that queries only return `Copy` types.
115 fn copy<T: Copy>(x: &T) -> T {
119 macro_rules! query_helper_param_ty {
120 (DefId) => { impl IntoQueryParam<DefId> };
121 (LocalDefId) => { impl IntoQueryParam<LocalDefId> };
125 macro_rules! query_storage {
126 ([][$K:ty, $V:ty]) => {
127 <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache
129 ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
130 <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::ArenaCache
132 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
133 query_storage!([$($modifiers)*][$($args)*])
137 macro_rules! separate_provide_extern_decl {
138 ([][$name:ident]) => {
141 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
144 query_keys::$name<'tcx>,
145 ) -> query_values::$name<'tcx>
147 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
148 separate_provide_extern_decl!([$($modifiers)*][$($args)*])
152 macro_rules! separate_provide_extern_default {
153 ([][$name:ident]) => {
156 ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
158 "`tcx.{}({:?})` unsupported by its crate; \
159 perhaps the `{}` query was never assigned a provider function",
165 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
166 separate_provide_extern_default!([$($modifiers)*][$($args)*])
170 macro_rules! opt_remap_env_constness {
171 ([][$name:ident]) => {};
172 ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
173 let $name = $name.without_const();
175 ([$other:tt $($modifiers:tt)*][$name:ident]) => {
176 opt_remap_env_constness!([$($modifiers)*][$name])
180 macro_rules! define_callbacks {
183 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
185 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
186 // below, but using type aliases instead of associated types, to bypass
187 // the limitations around normalizing under HRTB - for example, this:
188 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
189 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
190 // This is primarily used by the `provide!` macro in `rustc_metadata`.
191 #[allow(nonstandard_style, unused_lifetimes)]
195 $(pub type $name<'tcx> = $($K)*;)*
197 #[allow(nonstandard_style, unused_lifetimes)]
198 pub mod query_values {
201 $(pub type $name<'tcx> = $V;)*
203 #[allow(nonstandard_style, unused_lifetimes)]
204 pub mod query_storage {
207 $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
209 #[allow(nonstandard_style, unused_lifetimes)]
210 pub mod query_stored {
213 $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
217 pub struct QueryCaches<'tcx> {
218 $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
221 impl<'tcx> TyCtxtEnsure<'tcx> {
224 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
225 let key = key.into_query_param();
226 opt_remap_env_constness!([$($modifiers)*][key]);
228 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
235 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
239 impl<'tcx> TyCtxt<'tcx> {
243 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
245 self.at(DUMMY_SP).$name(key)
249 impl<'tcx> TyCtxtAt<'tcx> {
252 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
254 let key = key.into_query_param();
255 opt_remap_env_constness!([$($modifiers)*][key]);
257 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
260 Ok(value) => return value,
264 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
268 pub struct Providers {
269 $(pub $name: for<'tcx> fn(
271 query_keys::$name<'tcx>,
272 ) -> query_values::$name<'tcx>,)*
275 pub struct ExternProviders {
276 $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
279 impl Default for Providers {
280 fn default() -> Self {
281 use crate::query::Key;
284 $($name: |_, key| bug!(
285 "`tcx.{}({:?})` is not supported for {} crate;\n
286 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
287 If that's not the case, {} was likely never assigned to a provider function.\n",
290 if key.query_crate_is_local() { "local" } else { "external" },
297 impl Default for ExternProviders {
298 fn default() -> Self {
300 $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
305 impl Copy for Providers {}
306 impl Clone for Providers {
307 fn clone(&self) -> Self { *self }
310 impl Copy for ExternProviders {}
311 impl Clone for ExternProviders {
312 fn clone(&self) -> Self { *self }
315 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
316 fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
318 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
325 key: query_keys::$name<'tcx>,
327 ) -> Option<query_stored::$name<'tcx>>;)*
332 macro_rules! hash_result {
334 Some(dep_graph::hash_result)
336 ([(no_hash) $($rest:tt)*]) => {{
339 ([$other:tt $($modifiers:tt)*]) => {
340 hash_result!([$($modifiers)*])
344 macro_rules! define_feedable {
345 ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
346 $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
349 pub fn $name(self, value: $V) -> query_stored::$name<'tcx> {
350 let key = self.key().into_query_param();
351 opt_remap_env_constness!([$($modifiers)*][key]);
354 let cache = &tcx.query_caches.$name;
356 let cached = try_get_cached(tcx, cache, &key, copy);
361 "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
368 let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key);
369 let dep_node_index = tcx.dep_graph.with_feed_task(
374 hash_result!([$($modifiers)*]),
376 cache.complete(key, value, dep_node_index)
382 // Each of these queries corresponds to a function pointer field in the
383 // `Providers` struct for requesting a value of that type, and a method
384 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
385 // which memoizes and does dep-graph tracking, wrapping around the actual
386 // `Providers` that the driver creates (using several `rustc_*` crates).
388 // The result type of each query must implement `Clone`, and additionally
389 // `ty::query::values::Value`, which produces an appropriate placeholder
390 // (error) value if the query resulted in a query cycle.
391 // Queries marked with `fatal_cycle` do not need the latter implementation,
392 // as they will raise an fatal error on query cycles instead.
394 rustc_query_append! { define_callbacks! }
395 rustc_feedable_queries! { define_feedable! }
398 use super::{DefId, LocalDefId, OwnerId};
400 /// An analogue of the `Into` trait that's intended only for query parameters.
402 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
403 /// user call `to_def_id` to convert between them everywhere else.
404 pub trait IntoQueryParam<P> {
405 fn into_query_param(self) -> P;
408 impl<P> IntoQueryParam<P> for P {
410 fn into_query_param(self) -> P {
415 impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
417 fn into_query_param(self) -> P {
422 impl IntoQueryParam<LocalDefId> for OwnerId {
424 fn into_query_param(self) -> LocalDefId {
429 impl IntoQueryParam<DefId> for LocalDefId {
431 fn into_query_param(self) -> DefId {
436 impl IntoQueryParam<DefId> for OwnerId {
438 fn into_query_param(self) -> DefId {
444 use sealed::IntoQueryParam;
446 impl<'tcx> TyCtxt<'tcx> {
447 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
448 let def_id = def_id.into_query_param();
449 self.opt_def_kind(def_id)
450 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
453 pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
454 ty::EarlyBinder(self.type_of(def_id))
458 impl<'tcx> TyCtxtAt<'tcx> {
459 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
460 let def_id = def_id.into_query_param();
461 self.opt_def_kind(def_id)
462 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
465 pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
466 ty::EarlyBinder(self.type_of(def_id))