]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/query/mod.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / compiler / rustc_middle / src / ty / query / mod.rs
CommitLineData
5869c6ff 1use crate::dep_graph;
dfeec247 2use crate::hir::exports::Export;
ba9703b0 3use crate::hir::map;
9fa01778 4use crate::infer::canonical::{self, Canonical};
dfeec247
XL
5use crate::lint::LintLevelMap;
6use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
3dfed10e 7use crate::middle::cstore::{CrateDepKind, CrateSource};
f9f354fc 8use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
dfeec247 9use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
dfeec247 10use crate::middle::lib_features::LibFeatures;
9fa01778 11use crate::middle::privacy::AccessLevels;
9fa01778 12use crate::middle::region;
dfeec247 13use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
9fa01778 14use crate::middle::stability::{self, DeprecationEntry};
9fa01778
XL
15use crate::mir;
16use crate::mir::interpret::GlobalId;
6a06907d 17use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput};
1b1a35ee 18use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult};
dfeec247 19use crate::mir::mono::CodegenUnit;
dfeec247
XL
20use crate::traits::query::{
21 CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
22 CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
23 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
24};
74b04a01
XL
25use crate::traits::query::{
26 DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
27 OutlivesBound,
28};
9fa01778 29use crate::traits::specialization_graph;
f035d41b 30use crate::traits::{self, ImplSource};
ba9703b0 31use crate::ty::subst::{GenericArg, SubstsRef};
74b04a01 32use crate::ty::util::AlwaysRequiresDrop;
dfeec247 33use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
dfeec247 34use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
ea8adc8c 35use rustc_data_structures::stable_hasher::StableVec;
fc512014 36use rustc_data_structures::steal::Steal;
dfeec247 37use rustc_data_structures::svh::Svh;
0bf4aa26 38use rustc_data_structures::sync::Lrc;
6a06907d 39use rustc_errors::{ErrorReported, Handler};
dfeec247
XL
40use rustc_hir as hir;
41use rustc_hir::def::DefKind;
ba9703b0
XL
42use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
43use rustc_hir::lang_items::{LangItem, LanguageItems};
3dfed10e
XL
44use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
45use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
6a06907d 46use rustc_serialize::opaque;
ba9703b0 47use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
f9f354fc 48use rustc_session::utils::NativeLibKind;
ba9703b0 49use rustc_session::CrateDisambiguator;
0bf4aa26 50use rustc_target::spec::PanicStrategy;
ea8adc8c 51
3dfed10e 52use rustc_ast as ast;
74b04a01 53use rustc_attr as attr;
dfeec247
XL
54use rustc_span::symbol::Symbol;
55use rustc_span::{Span, DUMMY_SP};
ba9703b0 56use std::collections::BTreeMap;
ea8adc8c 57use std::ops::Deref;
f035d41b 58use std::path::PathBuf;
ea8adc8c 59use std::sync::Arc;
ea8adc8c 60
6a06907d 61pub(crate) use rustc_query_system::query::QueryJobId;
ba9703b0 62use rustc_query_system::query::*;
74b04a01 63
6a06907d
XL
64pub mod on_disk_cache;
65pub use self::on_disk_cache::OnDiskCache;
ea8adc8c 66
6a06907d
XL
67#[derive(Copy, Clone)]
68pub struct TyCtxtAt<'tcx> {
69 pub tcx: TyCtxt<'tcx>,
70 pub span: Span,
71}
83c7162d 72
6a06907d
XL
73impl Deref for TyCtxtAt<'tcx> {
74 type Target = TyCtxt<'tcx>;
75 #[inline(always)]
76 fn deref(&self) -> &Self::Target {
77 &self.tcx
78 }
79}
ea8adc8c 80
6a06907d
XL
81#[derive(Copy, Clone)]
82pub struct TyCtxtEnsure<'tcx> {
83 pub tcx: TyCtxt<'tcx>,
84}
ea8adc8c 85
6a06907d
XL
86impl TyCtxt<'tcx> {
87 /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
88 /// are executed instead of just returning their results.
89 #[inline(always)]
90 pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
91 TyCtxtEnsure { tcx: self }
92 }
ea8adc8c 93
6a06907d
XL
94 /// Returns a transparent wrapper for `TyCtxt` which uses
95 /// `span` as the location of queries performed through it.
96 #[inline(always)]
97 pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
98 TyCtxtAt { tcx: self, span }
99 }
100
101 pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
102 self.queries.try_mark_green(self, dep_node)
103 }
104}
105
106macro_rules! query_helper_param_ty {
107 (DefId) => { impl IntoQueryParam<DefId> };
108 ($K:ty) => { $K };
109}
110
111macro_rules! query_storage {
112 ([][$K:ty, $V:ty]) => {
113 <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
114 };
115 ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
116 <$ty as CacheSelector<$K, $V>>::Cache
117 };
118 ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
119 query_storage!([$($($modifiers)*)*][$($args)*])
120 };
121}
122
123macro_rules! define_callbacks {
124 (<$tcx:tt>
125 $($(#[$attr:meta])*
126 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
127
128 // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
129 // below, but using type aliases instead of associated types, to bypass
130 // the limitations around normalizing under HRTB - for example, this:
131 // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
132 // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
133 // This is primarily used by the `provide!` macro in `rustc_metadata`.
134 #[allow(nonstandard_style, unused_lifetimes)]
135 pub mod query_keys {
136 use super::*;
137
138 $(pub type $name<$tcx> = $($K)*;)*
139 }
140 #[allow(nonstandard_style, unused_lifetimes)]
141 pub mod query_values {
142 use super::*;
143
144 $(pub type $name<$tcx> = $V;)*
145 }
146 #[allow(nonstandard_style, unused_lifetimes)]
147 pub mod query_storage {
148 use super::*;
149
150 $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
151 }
152 #[allow(nonstandard_style, unused_lifetimes)]
153 pub mod query_stored {
154 use super::*;
155
156 $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
157 }
158
159 #[derive(Default)]
160 pub struct QueryCaches<$tcx> {
161 $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
162 }
163
164 impl TyCtxtEnsure<$tcx> {
165 $($(#[$attr])*
166 #[inline(always)]
167 pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
168 let key = key.into_query_param();
169 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {});
170
171 let lookup = match cached {
172 Ok(()) => return,
173 Err(lookup) => lookup,
174 };
175
176 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
177 })*
178 }
179
180 impl TyCtxt<$tcx> {
181 $($(#[$attr])*
182 #[inline(always)]
183 #[must_use]
184 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
185 {
186 self.at(DUMMY_SP).$name(key)
187 })*
188 }
189
190 impl TyCtxtAt<$tcx> {
191 $($(#[$attr])*
192 #[inline(always)]
193 pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
194 {
195 let key = key.into_query_param();
196 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| {
197 value.clone()
198 });
199
200 let lookup = match cached {
201 Ok(value) => return value,
202 Err(lookup) => lookup,
203 };
204
205 self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
206 })*
207 }
208
209 pub struct Providers {
210 $(pub $name: for<'tcx> fn(
211 TyCtxt<'tcx>,
212 query_keys::$name<'tcx>,
213 ) -> query_values::$name<'tcx>,)*
214 }
215
216 impl Default for Providers {
217 fn default() -> Self {
218 Providers {
219 $($name: |_, key| bug!(
220 "`tcx.{}({:?})` unsupported by its crate",
221 stringify!($name), key
222 ),)*
223 }
224 }
225 }
226
227 impl Copy for Providers {}
228 impl Clone for Providers {
229 fn clone(&self) -> Self { *self }
230 }
231
232 pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
233 unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry);
234
235 fn encode_query_results(
236 &'tcx self,
237 tcx: TyCtxt<'tcx>,
238 encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
239 query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
240 ) -> opaque::FileEncodeResult;
241
242 fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>);
243
244 fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
245
246 fn try_print_query_stack(
247 &'tcx self,
248 tcx: TyCtxt<'tcx>,
249 query: Option<QueryJobId<dep_graph::DepKind>>,
250 handler: &Handler,
251 num_frames: Option<usize>,
252 ) -> usize;
abe05a73 253
6a06907d
XL
254 $($(#[$attr])*
255 fn $name(
256 &'tcx self,
257 tcx: TyCtxt<$tcx>,
258 span: Span,
259 key: query_keys::$name<$tcx>,
260 lookup: QueryLookup,
261 mode: QueryMode,
262 ) -> Option<query_stored::$name<$tcx>>;)*
263 }
264 };
265}
dfeec247 266
532ac7d7 267// Each of these queries corresponds to a function pointer field in the
94b46f34
XL
268// `Providers` struct for requesting a value of that type, and a method
269// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
270// which memoizes and does dep-graph tracking, wrapping around the actual
271// `Providers` that the driver creates (using several `rustc_*` crates).
0531ce1d 272//
94b46f34
XL
273// The result type of each query must implement `Clone`, and additionally
274// `ty::query::values::Value`, which produces an appropriate placeholder
275// (error) value if the query resulted in a query cycle.
276// Queries marked with `fatal_cycle` do not need the latter implementation,
0531ce1d 277// as they will raise an fatal error on query cycles instead.
8faf50e0 278
6a06907d 279rustc_query_append! { [define_callbacks!][<'tcx>] }
74b04a01 280
ba9703b0
XL
281mod sealed {
282 use super::{DefId, LocalDefId};
283
284 /// An analogue of the `Into` trait that's intended only for query paramaters.
285 ///
286 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
287 /// user call `to_def_id` to convert between them everywhere else.
288 pub trait IntoQueryParam<P> {
289 fn into_query_param(self) -> P;
290 }
291
292 impl<P> IntoQueryParam<P> for P {
293 #[inline(always)]
294 fn into_query_param(self) -> P {
295 self
296 }
297 }
74b04a01 298
ba9703b0
XL
299 impl IntoQueryParam<DefId> for LocalDefId {
300 #[inline(always)]
301 fn into_query_param(self) -> DefId {
302 self.to_def_id()
303 }
74b04a01
XL
304 }
305}
ba9703b0
XL
306
307use sealed::IntoQueryParam;
5869c6ff
XL
308
309impl TyCtxt<'tcx> {
310 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
311 let def_id = def_id.into_query_param();
312 self.opt_def_kind(def_id)
313 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
314 }
315}
316
317impl TyCtxtAt<'tcx> {
318 pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
319 let def_id = def_id.into_query_param();
320 self.opt_def_kind(def_id)
321 .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
322 }
323}