]>
Commit | Line | Data |
---|---|---|
5869c6ff | 1 | use crate::dep_graph; |
dfeec247 | 2 | use crate::hir::exports::Export; |
ba9703b0 | 3 | use crate::hir::map; |
9fa01778 | 4 | use crate::infer::canonical::{self, Canonical}; |
dfeec247 XL |
5 | use crate::lint::LintLevelMap; |
6 | use crate::middle::codegen_fn_attrs::CodegenFnAttrs; | |
3dfed10e | 7 | use crate::middle::cstore::{CrateDepKind, CrateSource}; |
f9f354fc | 8 | use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; |
dfeec247 | 9 | use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; |
dfeec247 | 10 | use crate::middle::lib_features::LibFeatures; |
9fa01778 | 11 | use crate::middle::privacy::AccessLevels; |
9fa01778 | 12 | use crate::middle::region; |
dfeec247 | 13 | use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes}; |
9fa01778 | 14 | use crate::middle::stability::{self, DeprecationEntry}; |
9fa01778 XL |
15 | use crate::mir; |
16 | use crate::mir::interpret::GlobalId; | |
6a06907d | 17 | use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput}; |
1b1a35ee | 18 | use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult}; |
dfeec247 | 19 | use crate::mir::mono::CodegenUnit; |
dfeec247 XL |
20 | use crate::traits::query::{ |
21 | CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, | |
22 | CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, | |
23 | CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution, | |
24 | }; | |
74b04a01 XL |
25 | use crate::traits::query::{ |
26 | DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult, | |
27 | OutlivesBound, | |
28 | }; | |
9fa01778 | 29 | use crate::traits::specialization_graph; |
f035d41b | 30 | use crate::traits::{self, ImplSource}; |
ba9703b0 | 31 | use crate::ty::subst::{GenericArg, SubstsRef}; |
74b04a01 | 32 | use crate::ty::util::AlwaysRequiresDrop; |
dfeec247 | 33 | use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; |
dfeec247 | 34 | use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; |
ea8adc8c | 35 | use rustc_data_structures::stable_hasher::StableVec; |
fc512014 | 36 | use rustc_data_structures::steal::Steal; |
dfeec247 | 37 | use rustc_data_structures::svh::Svh; |
0bf4aa26 | 38 | use rustc_data_structures::sync::Lrc; |
6a06907d | 39 | use rustc_errors::{ErrorReported, Handler}; |
dfeec247 XL |
40 | use rustc_hir as hir; |
41 | use rustc_hir::def::DefKind; | |
ba9703b0 XL |
42 | use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; |
43 | use rustc_hir::lang_items::{LangItem, LanguageItems}; | |
3dfed10e XL |
44 | use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; |
45 | use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; | |
6a06907d | 46 | use rustc_serialize::opaque; |
ba9703b0 | 47 | use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; |
f9f354fc | 48 | use rustc_session::utils::NativeLibKind; |
ba9703b0 | 49 | use rustc_session::CrateDisambiguator; |
0bf4aa26 | 50 | use rustc_target::spec::PanicStrategy; |
ea8adc8c | 51 | |
3dfed10e | 52 | use rustc_ast as ast; |
74b04a01 | 53 | use rustc_attr as attr; |
dfeec247 XL |
54 | use rustc_span::symbol::Symbol; |
55 | use rustc_span::{Span, DUMMY_SP}; | |
ba9703b0 | 56 | use std::collections::BTreeMap; |
ea8adc8c | 57 | use std::ops::Deref; |
f035d41b | 58 | use std::path::PathBuf; |
ea8adc8c | 59 | use std::sync::Arc; |
ea8adc8c | 60 | |
6a06907d | 61 | pub(crate) use rustc_query_system::query::QueryJobId; |
ba9703b0 | 62 | use rustc_query_system::query::*; |
74b04a01 | 63 | |
6a06907d XL |
64 | pub mod on_disk_cache; |
65 | pub use self::on_disk_cache::OnDiskCache; | |
ea8adc8c | 66 | |
6a06907d XL |
67 | #[derive(Copy, Clone)] |
68 | pub struct TyCtxtAt<'tcx> { | |
69 | pub tcx: TyCtxt<'tcx>, | |
70 | pub span: Span, | |
71 | } | |
83c7162d | 72 | |
6a06907d XL |
73 | impl 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)] |
82 | pub struct TyCtxtEnsure<'tcx> { | |
83 | pub tcx: TyCtxt<'tcx>, | |
84 | } | |
ea8adc8c | 85 | |
6a06907d XL |
86 | impl 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 | ||
106 | macro_rules! query_helper_param_ty { | |
107 | (DefId) => { impl IntoQueryParam<DefId> }; | |
108 | ($K:ty) => { $K }; | |
109 | } | |
110 | ||
111 | macro_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 | ||
123 | macro_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 | 279 | rustc_query_append! { [define_callbacks!][<'tcx>] } |
74b04a01 | 280 | |
ba9703b0 XL |
281 | mod 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 | |
307 | use sealed::IntoQueryParam; | |
5869c6ff XL |
308 | |
309 | impl 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 | ||
317 | impl 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 | } |