]>
Commit | Line | Data |
---|---|---|
6a06907d XL |
1 | //! The implementation of the query system itself. This defines the macros that |
2 | //! generate the actual methods on tcx which find and execute the provider, | |
3 | //! manage the caches, and so forth. | |
4 | ||
3c0e092e | 5 | use crate::{on_disk_cache, Queries}; |
5099ac24 | 6 | use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; |
6a06907d | 7 | use rustc_middle::ty::tls::{self, ImplicitCtxt}; |
3c0e092e | 8 | use rustc_middle::ty::TyCtxt; |
6a06907d | 9 | use rustc_query_system::dep_graph::HasDepContext; |
3c0e092e | 10 | use rustc_query_system::query::{QueryContext, QueryJobId, QueryMap, QuerySideEffects}; |
6a06907d XL |
11 | |
12 | use rustc_data_structures::sync::Lock; | |
13 | use rustc_data_structures::thin_vec::ThinVec; | |
136023e0 | 14 | use rustc_errors::{Diagnostic, Handler}; |
6a06907d | 15 | |
136023e0 | 16 | use std::any::Any; |
5099ac24 | 17 | use std::num::NonZeroU64; |
136023e0 | 18 | |
6a06907d XL |
19 | #[derive(Copy, Clone)] |
20 | pub struct QueryCtxt<'tcx> { | |
21 | pub tcx: TyCtxt<'tcx>, | |
136023e0 | 22 | pub queries: &'tcx Queries<'tcx>, |
6a06907d XL |
23 | } |
24 | ||
25 | impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> { | |
26 | type Target = TyCtxt<'tcx>; | |
27 | ||
17df50a5 | 28 | #[inline] |
6a06907d XL |
29 | fn deref(&self) -> &Self::Target { |
30 | &self.tcx | |
31 | } | |
32 | } | |
33 | ||
a2a8927a | 34 | impl<'tcx> HasDepContext for QueryCtxt<'tcx> { |
6a06907d | 35 | type DepKind = rustc_middle::dep_graph::DepKind; |
6a06907d XL |
36 | type DepContext = TyCtxt<'tcx>; |
37 | ||
38 | #[inline] | |
39 | fn dep_context(&self) -> &Self::DepContext { | |
40 | &self.tcx | |
41 | } | |
42 | } | |
43 | ||
a2a8927a | 44 | impl QueryContext for QueryCtxt<'_> { |
5099ac24 FG |
45 | fn next_job_id(&self) -> QueryJobId { |
46 | QueryJobId( | |
47 | NonZeroU64::new( | |
48 | self.queries.jobs.fetch_add(1, rustc_data_structures::sync::Ordering::Relaxed), | |
49 | ) | |
50 | .unwrap(), | |
51 | ) | |
52 | } | |
53 | ||
54 | fn current_query_job(&self) -> Option<QueryJobId> { | |
6a06907d XL |
55 | tls::with_related_context(**self, |icx| icx.query) |
56 | } | |
57 | ||
5099ac24 | 58 | fn try_collect_active_jobs(&self) -> Option<QueryMap> { |
6a06907d XL |
59 | self.queries.try_collect_active_jobs(**self) |
60 | } | |
61 | ||
6a06907d | 62 | // Interactions with on_disk_cache |
94222f64 | 63 | fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects { |
136023e0 XL |
64 | self.queries |
65 | .on_disk_cache | |
6a06907d | 66 | .as_ref() |
94222f64 | 67 | .map(|c| c.load_side_effects(**self, prev_dep_node_index)) |
6a06907d XL |
68 | .unwrap_or_default() |
69 | } | |
70 | ||
94222f64 | 71 | fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) { |
136023e0 | 72 | if let Some(c) = self.queries.on_disk_cache.as_ref() { |
94222f64 | 73 | c.store_side_effects(dep_node_index, side_effects) |
6a06907d XL |
74 | } |
75 | } | |
76 | ||
94222f64 | 77 | fn store_side_effects_for_anon_node( |
6a06907d XL |
78 | &self, |
79 | dep_node_index: DepNodeIndex, | |
94222f64 | 80 | side_effects: QuerySideEffects, |
6a06907d | 81 | ) { |
136023e0 | 82 | if let Some(c) = self.queries.on_disk_cache.as_ref() { |
94222f64 | 83 | c.store_side_effects_for_anon_node(dep_node_index, side_effects) |
6a06907d XL |
84 | } |
85 | } | |
86 | ||
87 | /// Executes a job by changing the `ImplicitCtxt` to point to the | |
88 | /// new query job while it executes. It returns the diagnostics | |
89 | /// captured during execution and the actual result. | |
90 | #[inline(always)] | |
91 | fn start_query<R>( | |
92 | &self, | |
5099ac24 | 93 | token: QueryJobId, |
6a06907d XL |
94 | diagnostics: Option<&Lock<ThinVec<Diagnostic>>>, |
95 | compute: impl FnOnce() -> R, | |
96 | ) -> R { | |
97 | // The `TyCtxt` stored in TLS has the same global interner lifetime | |
98 | // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes | |
99 | // when accessing the `ImplicitCtxt`. | |
100 | tls::with_related_context(**self, move |current_icx| { | |
101 | // Update the `ImplicitCtxt` to point to our new query job. | |
102 | let new_icx = ImplicitCtxt { | |
103 | tcx: **self, | |
104 | query: Some(token), | |
105 | diagnostics, | |
106 | layout_depth: current_icx.layout_depth, | |
107 | task_deps: current_icx.task_deps, | |
108 | }; | |
109 | ||
110 | // Use the `ImplicitCtxt` while we execute the query. | |
111 | tls::enter_context(&new_icx, |_| { | |
112 | rustc_data_structures::stack::ensure_sufficient_stack(compute) | |
113 | }) | |
114 | }) | |
115 | } | |
116 | } | |
117 | ||
118 | impl<'tcx> QueryCtxt<'tcx> { | |
136023e0 XL |
119 | #[inline] |
120 | pub fn from_tcx(tcx: TyCtxt<'tcx>) -> Self { | |
121 | let queries = tcx.queries.as_any(); | |
122 | let queries = unsafe { | |
123 | let queries = std::mem::transmute::<&dyn Any, &dyn Any>(queries); | |
124 | let queries = queries.downcast_ref().unwrap(); | |
125 | let queries = std::mem::transmute::<&Queries<'_>, &Queries<'_>>(queries); | |
126 | queries | |
127 | }; | |
128 | QueryCtxt { tcx, queries } | |
129 | } | |
130 | ||
923072b8 | 131 | pub(crate) fn on_disk_cache(self) -> Option<&'tcx on_disk_cache::OnDiskCache<'tcx>> { |
136023e0 XL |
132 | self.queries.on_disk_cache.as_ref() |
133 | } | |
134 | ||
6a06907d XL |
135 | pub(super) fn encode_query_results( |
136 | self, | |
923072b8 | 137 | encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>, |
94222f64 | 138 | query_result_index: &mut on_disk_cache::EncodedDepNodeIndex, |
923072b8 | 139 | ) { |
6a06907d XL |
140 | macro_rules! encode_queries { |
141 | ($($query:ident,)*) => { | |
142 | $( | |
143 | on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>( | |
144 | self, | |
145 | encoder, | |
146 | query_result_index | |
923072b8 | 147 | ); |
6a06907d XL |
148 | )* |
149 | } | |
150 | } | |
151 | ||
152 | rustc_cached_queries!(encode_queries!); | |
6a06907d | 153 | } |
136023e0 XL |
154 | |
155 | pub fn try_print_query_stack( | |
156 | self, | |
5099ac24 | 157 | query: Option<QueryJobId>, |
136023e0 XL |
158 | handler: &Handler, |
159 | num_frames: Option<usize>, | |
160 | ) -> usize { | |
161 | rustc_query_system::query::print_query_stack(self, query, handler, num_frames) | |
162 | } | |
6a06907d XL |
163 | } |
164 | ||
6a06907d XL |
165 | macro_rules! handle_cycle_error { |
166 | ([][$tcx: expr, $error:expr]) => {{ | |
167 | $error.emit(); | |
168 | Value::from_cycle_error($tcx) | |
169 | }}; | |
c295e0f8 | 170 | ([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{ |
6a06907d XL |
171 | $error.emit(); |
172 | $tcx.sess.abort_if_errors(); | |
173 | unreachable!() | |
174 | }}; | |
c295e0f8 | 175 | ([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{ |
6a06907d XL |
176 | $error.delay_as_bug(); |
177 | Value::from_cycle_error($tcx) | |
178 | }}; | |
c295e0f8 XL |
179 | ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { |
180 | handle_cycle_error!([$($modifiers)*][$($args)*]) | |
6a06907d XL |
181 | }; |
182 | } | |
183 | ||
184 | macro_rules! is_anon { | |
185 | ([]) => {{ | |
186 | false | |
187 | }}; | |
c295e0f8 | 188 | ([(anon) $($rest:tt)*]) => {{ |
6a06907d XL |
189 | true |
190 | }}; | |
c295e0f8 XL |
191 | ([$other:tt $($modifiers:tt)*]) => { |
192 | is_anon!([$($modifiers)*]) | |
6a06907d XL |
193 | }; |
194 | } | |
195 | ||
196 | macro_rules! is_eval_always { | |
197 | ([]) => {{ | |
198 | false | |
199 | }}; | |
c295e0f8 | 200 | ([(eval_always) $($rest:tt)*]) => {{ |
6a06907d XL |
201 | true |
202 | }}; | |
c295e0f8 XL |
203 | ([$other:tt $($modifiers:tt)*]) => { |
204 | is_eval_always!([$($modifiers)*]) | |
6a06907d XL |
205 | }; |
206 | } | |
207 | ||
208 | macro_rules! hash_result { | |
3c0e092e XL |
209 | ([]) => {{ |
210 | Some(dep_graph::hash_result) | |
6a06907d | 211 | }}; |
3c0e092e | 212 | ([(no_hash) $($rest:tt)*]) => {{ |
6a06907d XL |
213 | None |
214 | }}; | |
3c0e092e XL |
215 | ([$other:tt $($modifiers:tt)*]) => { |
216 | hash_result!([$($modifiers)*]) | |
217 | }; | |
218 | } | |
219 | ||
220 | macro_rules! get_provider { | |
221 | ([][$tcx:expr, $name:ident, $key:expr]) => {{ | |
222 | $tcx.queries.local_providers.$name | |
223 | }}; | |
224 | ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{ | |
225 | if $key.query_crate_is_local() { | |
226 | $tcx.queries.local_providers.$name | |
227 | } else { | |
228 | $tcx.queries.extern_providers.$name | |
229 | } | |
230 | }}; | |
c295e0f8 | 231 | ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { |
3c0e092e | 232 | get_provider!([$($modifiers)*][$($args)*]) |
6a06907d XL |
233 | }; |
234 | } | |
235 | ||
a2a8927a XL |
236 | macro_rules! opt_remap_env_constness { |
237 | ([][$name:ident]) => {}; | |
238 | ([(remap_env_constness) $($rest:tt)*][$name:ident]) => { | |
239 | let $name = $name.without_const(); | |
240 | }; | |
241 | ([$other:tt $($modifiers:tt)*][$name:ident]) => { | |
242 | opt_remap_env_constness!([$($modifiers)*][$name]) | |
243 | }; | |
244 | } | |
245 | ||
6a06907d XL |
246 | macro_rules! define_queries { |
247 | (<$tcx:tt> | |
248 | $($(#[$attr:meta])* | |
249 | [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { | |
250 | ||
251 | define_queries_struct! { | |
252 | tcx: $tcx, | |
253 | input: ($(([$($modifiers)*] [$($attr)*] [$name]))*) | |
254 | } | |
255 | ||
256 | mod make_query { | |
257 | use super::*; | |
258 | ||
259 | // Create an eponymous constructor for each query. | |
260 | $(#[allow(nonstandard_style)] $(#[$attr])* | |
261 | pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame { | |
a2a8927a | 262 | opt_remap_env_constness!([$($modifiers)*][key]); |
6a06907d XL |
263 | let kind = dep_graph::DepKind::$name; |
264 | let name = stringify!($name); | |
c295e0f8 XL |
265 | // Disable visible paths printing for performance reasons. |
266 | // Showing visible path instead of any path is not that important in production. | |
5e7ed085 | 267 | let description = ty::print::with_no_visible_paths!( |
6a06907d | 268 | // Force filename-line mode to avoid invoking `type_of` query. |
5e7ed085 FG |
269 | ty::print::with_forced_impl_filename_line!( |
270 | queries::$name::describe(tcx, key) | |
271 | ) | |
272 | ); | |
6a06907d XL |
273 | let description = if tcx.sess.verbose() { |
274 | format!("{} [{}]", description, name) | |
275 | } else { | |
276 | description | |
277 | }; | |
278 | let span = if kind == dep_graph::DepKind::def_span { | |
279 | // The `def_span` query is used to calculate `default_span`, | |
280 | // so exit to avoid infinite recursion. | |
281 | None | |
282 | } else { | |
283 | Some(key.default_span(*tcx)) | |
284 | }; | |
064997fb FG |
285 | let def_kind = if kind == dep_graph::DepKind::opt_def_kind { |
286 | // Try to avoid infinite recursion. | |
287 | None | |
288 | } else { | |
289 | key.key_as_def_id() | |
290 | .and_then(|def_id| def_id.as_local()) | |
291 | .and_then(|def_id| tcx.opt_def_kind(def_id)) | |
292 | }; | |
6a06907d | 293 | let hash = || { |
064997fb FG |
294 | tcx.with_stable_hashing_context(|mut hcx|{ |
295 | let mut hasher = StableHasher::new(); | |
296 | std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher); | |
297 | key.hash_stable(&mut hcx, &mut hasher); | |
298 | hasher.finish::<u64>() | |
299 | }) | |
6a06907d XL |
300 | }; |
301 | ||
94222f64 | 302 | QueryStackFrame::new(name, description, span, def_kind, hash) |
6a06907d XL |
303 | })* |
304 | } | |
305 | ||
306 | #[allow(nonstandard_style)] | |
5099ac24 | 307 | mod queries { |
6a06907d XL |
308 | use std::marker::PhantomData; |
309 | ||
310 | $(pub struct $name<$tcx> { | |
311 | data: PhantomData<&$tcx ()> | |
312 | })* | |
313 | } | |
314 | ||
315 | $(impl<$tcx> QueryConfig for queries::$name<$tcx> { | |
316 | type Key = query_keys::$name<$tcx>; | |
317 | type Value = query_values::$name<$tcx>; | |
318 | type Stored = query_stored::$name<$tcx>; | |
319 | const NAME: &'static str = stringify!($name); | |
320 | } | |
321 | ||
3c0e092e XL |
322 | impl<$tcx> QueryDescription<QueryCtxt<$tcx>> for queries::$name<$tcx> { |
323 | rustc_query_description! { $name<$tcx> } | |
6a06907d XL |
324 | |
325 | type Cache = query_storage::$name<$tcx>; | |
326 | ||
327 | #[inline(always)] | |
5099ac24 | 328 | fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<Self::Key> |
6a06907d XL |
329 | where QueryCtxt<$tcx>: 'a |
330 | { | |
331 | &tcx.queries.$name | |
332 | } | |
333 | ||
334 | #[inline(always)] | |
5e7ed085 | 335 | fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a Self::Cache |
6a06907d XL |
336 | where 'tcx:'a |
337 | { | |
338 | &tcx.query_caches.$name | |
339 | } | |
340 | ||
341 | #[inline] | |
3c0e092e | 342 | fn make_vtable(tcx: QueryCtxt<'tcx>, key: &Self::Key) -> |
064997fb | 343 | QueryVTable<QueryCtxt<$tcx>, Self::Key, Self::Value> |
136023e0 | 344 | { |
3c0e092e XL |
345 | let compute = get_provider!([$($modifiers)*][tcx, $name, key]); |
346 | let cache_on_disk = Self::cache_on_disk(tcx.tcx, key); | |
064997fb | 347 | QueryVTable { |
3c0e092e XL |
348 | anon: is_anon!([$($modifiers)*]), |
349 | eval_always: is_eval_always!([$($modifiers)*]), | |
350 | dep_kind: dep_graph::DepKind::$name, | |
351 | hash_result: hash_result!([$($modifiers)*]), | |
352 | handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]), | |
353 | compute, | |
354 | cache_on_disk, | |
355 | try_load_from_disk: Self::TRY_LOAD_FROM_DISK, | |
136023e0 | 356 | } |
6a06907d | 357 | } |
6a06907d XL |
358 | })* |
359 | ||
3c0e092e | 360 | #[allow(nonstandard_style)] |
5099ac24 | 361 | mod query_callbacks { |
6a06907d XL |
362 | use super::*; |
363 | use rustc_middle::dep_graph::DepNode; | |
364 | use rustc_middle::ty::query::query_keys; | |
365 | use rustc_query_system::dep_graph::DepNodeParams; | |
366 | use rustc_query_system::query::{force_query, QueryDescription}; | |
c295e0f8 | 367 | use rustc_query_system::dep_graph::FingerprintStyle; |
6a06907d XL |
368 | |
369 | // We use this for most things when incr. comp. is turned off. | |
3c0e092e XL |
370 | pub fn Null() -> DepKindStruct { |
371 | DepKindStruct { | |
372 | is_anon: false, | |
373 | is_eval_always: false, | |
374 | fingerprint_style: FingerprintStyle::Unit, | |
375 | force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)), | |
376 | try_load_from_on_disk_cache: None, | |
377 | } | |
378 | } | |
6a06907d | 379 | |
064997fb FG |
380 | // We use this for the forever-red node. |
381 | pub fn Red() -> DepKindStruct { | |
382 | DepKindStruct { | |
383 | is_anon: false, | |
384 | is_eval_always: false, | |
385 | fingerprint_style: FingerprintStyle::Unit, | |
386 | force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)), | |
387 | try_load_from_on_disk_cache: None, | |
388 | } | |
389 | } | |
390 | ||
3c0e092e XL |
391 | pub fn TraitSelect() -> DepKindStruct { |
392 | DepKindStruct { | |
393 | is_anon: true, | |
394 | is_eval_always: false, | |
395 | fingerprint_style: FingerprintStyle::Unit, | |
396 | force_from_dep_node: None, | |
397 | try_load_from_on_disk_cache: None, | |
398 | } | |
399 | } | |
6a06907d | 400 | |
3c0e092e XL |
401 | pub fn CompileCodegenUnit() -> DepKindStruct { |
402 | DepKindStruct { | |
403 | is_anon: false, | |
404 | is_eval_always: false, | |
405 | fingerprint_style: FingerprintStyle::Opaque, | |
406 | force_from_dep_node: None, | |
407 | try_load_from_on_disk_cache: None, | |
408 | } | |
409 | } | |
6a06907d | 410 | |
3c0e092e XL |
411 | pub fn CompileMonoItem() -> DepKindStruct { |
412 | DepKindStruct { | |
413 | is_anon: false, | |
414 | is_eval_always: false, | |
415 | fingerprint_style: FingerprintStyle::Opaque, | |
416 | force_from_dep_node: None, | |
417 | try_load_from_on_disk_cache: None, | |
418 | } | |
419 | } | |
cdc7bbd5 | 420 | |
5099ac24 | 421 | $(pub(crate) fn $name()-> DepKindStruct { |
3c0e092e XL |
422 | let is_anon = is_anon!([$($modifiers)*]); |
423 | let is_eval_always = is_eval_always!([$($modifiers)*]); | |
6a06907d | 424 | |
3c0e092e XL |
425 | let fingerprint_style = |
426 | <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::fingerprint_style(); | |
6a06907d | 427 | |
3c0e092e XL |
428 | if is_anon || !fingerprint_style.reconstructible() { |
429 | return DepKindStruct { | |
430 | is_anon, | |
431 | is_eval_always, | |
432 | fingerprint_style, | |
433 | force_from_dep_node: None, | |
434 | try_load_from_on_disk_cache: None, | |
435 | } | |
6a06907d XL |
436 | } |
437 | ||
3c0e092e XL |
438 | #[inline(always)] |
439 | fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> Option<query_keys::$name<'tcx>> { | |
440 | <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::recover(tcx, &dep_node) | |
6a06907d XL |
441 | } |
442 | ||
3c0e092e XL |
443 | fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool { |
444 | if let Some(key) = recover(tcx, dep_node) { | |
04454e1e FG |
445 | #[cfg(debug_assertions)] |
446 | let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); | |
3c0e092e XL |
447 | let tcx = QueryCtxt::from_tcx(tcx); |
448 | force_query::<queries::$name<'_>, _>(tcx, key, dep_node); | |
449 | true | |
450 | } else { | |
451 | false | |
6a06907d | 452 | } |
3c0e092e | 453 | } |
6a06907d | 454 | |
3c0e092e XL |
455 | fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: DepNode) { |
456 | debug_assert!(tcx.dep_graph.is_green(&dep_node)); | |
6a06907d | 457 | |
3c0e092e XL |
458 | let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); |
459 | if queries::$name::cache_on_disk(tcx, &key) { | |
6a06907d XL |
460 | let _ = tcx.$name(key); |
461 | } | |
462 | } | |
463 | ||
3c0e092e XL |
464 | DepKindStruct { |
465 | is_anon, | |
466 | is_eval_always, | |
467 | fingerprint_style, | |
468 | force_from_dep_node: Some(force_from_dep_node), | |
469 | try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache), | |
6a06907d | 470 | } |
3c0e092e | 471 | })* |
6a06907d XL |
472 | } |
473 | ||
3c0e092e XL |
474 | pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] { |
475 | arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) | |
476 | } | |
6a06907d XL |
477 | } |
478 | } | |
479 | ||
480 | // FIXME(eddyb) this macro (and others?) use `$tcx` and `'tcx` interchangeably. | |
481 | // We should either not take `$tcx` at all and use `'tcx` everywhere, or use | |
482 | // `$tcx` everywhere (even if that isn't necessary due to lack of hygiene). | |
483 | macro_rules! define_queries_struct { | |
484 | (tcx: $tcx:tt, | |
485 | input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { | |
486 | pub struct Queries<$tcx> { | |
cdc7bbd5 | 487 | local_providers: Box<Providers>, |
3c0e092e | 488 | extern_providers: Box<ExternProviders>, |
6a06907d | 489 | |
136023e0 XL |
490 | pub on_disk_cache: Option<OnDiskCache<$tcx>>, |
491 | ||
5099ac24 FG |
492 | jobs: AtomicU64, |
493 | ||
494 | $($(#[$attr])* $name: QueryState<query_keys::$name<$tcx>>,)* | |
6a06907d XL |
495 | } |
496 | ||
497 | impl<$tcx> Queries<$tcx> { | |
498 | pub fn new( | |
cdc7bbd5 | 499 | local_providers: Providers, |
3c0e092e | 500 | extern_providers: ExternProviders, |
136023e0 | 501 | on_disk_cache: Option<OnDiskCache<$tcx>>, |
6a06907d XL |
502 | ) -> Self { |
503 | Queries { | |
cdc7bbd5 XL |
504 | local_providers: Box::new(local_providers), |
505 | extern_providers: Box::new(extern_providers), | |
136023e0 | 506 | on_disk_cache, |
5099ac24 | 507 | jobs: AtomicU64::new(1), |
6a06907d XL |
508 | $($name: Default::default()),* |
509 | } | |
510 | } | |
511 | ||
512 | pub(crate) fn try_collect_active_jobs( | |
513 | &$tcx self, | |
514 | tcx: TyCtxt<$tcx>, | |
5099ac24 | 515 | ) -> Option<QueryMap> { |
6a06907d XL |
516 | let tcx = QueryCtxt { tcx, queries: self }; |
517 | let mut jobs = QueryMap::default(); | |
518 | ||
519 | $( | |
520 | self.$name.try_collect_active_jobs( | |
521 | tcx, | |
6a06907d XL |
522 | make_query::$name, |
523 | &mut jobs, | |
524 | )?; | |
525 | )* | |
526 | ||
527 | Some(jobs) | |
528 | } | |
529 | } | |
530 | ||
a2a8927a | 531 | impl<'tcx> QueryEngine<'tcx> for Queries<'tcx> { |
136023e0 XL |
532 | fn as_any(&'tcx self) -> &'tcx dyn std::any::Any { |
533 | let this = unsafe { std::mem::transmute::<&Queries<'_>, &Queries<'_>>(self) }; | |
534 | this as _ | |
6a06907d XL |
535 | } |
536 | ||
537 | fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool { | |
538 | let qcx = QueryCtxt { tcx, queries: self }; | |
539 | tcx.dep_graph.try_mark_green(qcx, dep_node).is_some() | |
540 | } | |
541 | ||
6a06907d XL |
542 | $($(#[$attr])* |
543 | #[inline(always)] | |
04454e1e | 544 | #[tracing::instrument(level = "trace", skip(self, tcx))] |
6a06907d XL |
545 | fn $name( |
546 | &'tcx self, | |
547 | tcx: TyCtxt<$tcx>, | |
548 | span: Span, | |
549 | key: query_keys::$name<$tcx>, | |
6a06907d XL |
550 | mode: QueryMode, |
551 | ) -> Option<query_stored::$name<$tcx>> { | |
a2a8927a | 552 | opt_remap_env_constness!([$($modifiers)*][key]); |
6a06907d | 553 | let qcx = QueryCtxt { tcx, queries: self }; |
5e7ed085 | 554 | get_query::<queries::$name<$tcx>, _>(qcx, span, key, mode) |
6a06907d XL |
555 | })* |
556 | } | |
557 | }; | |
558 | } |