1use std::num::NonZero;
6
7use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
8use rustc_data_structures::sync::Lock;
9use rustc_data_structures::unord::UnordMap;
10use rustc_errors::DiagInner;
11use rustc_index::Idx;
12use rustc_middle::bug;
13use rustc_middle::dep_graph::{
14 self, DepContext, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
15 dep_kinds,
16};
17use rustc_middle::query::Key;
18use rustc_middle::query::on_disk_cache::{
19 AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex,
20};
21use rustc_middle::ty::print::with_reduced_queries;
22use rustc_middle::ty::tls::{self, ImplicitCtxt};
23use rustc_middle::ty::{self, TyCtxt, TyEncoder};
24use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
25use rustc_query_system::ich::StableHashingContext;
26use rustc_query_system::query::{
27 QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
28 force_query,
29};
30use rustc_query_system::{QueryOverflow, QueryOverflowNote};
31use rustc_serialize::{Decodable, Encodable};
32use rustc_session::Limit;
33use rustc_span::def_id::LOCAL_CRATE;
34use thin_vec::ThinVec;
35
36use crate::QueryConfigRestored;
37
38#[derive(Copy, Clone)]
39pub struct QueryCtxt<'tcx> {
40 pub tcx: TyCtxt<'tcx>,
41}
42
43impl<'tcx> QueryCtxt<'tcx> {
44 #[inline]
45 pub fn new(tcx: TyCtxt<'tcx>) -> Self {
46 QueryCtxt { tcx }
47 }
48}
49
50impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> {
51 type Target = TyCtxt<'tcx>;
52
53 #[inline]
54 fn deref(&self) -> &Self::Target {
55 &self.tcx
56 }
57}
58
59impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
60 type Deps = rustc_middle::dep_graph::DepsType;
61 type DepContext = TyCtxt<'tcx>;
62
63 #[inline]
64 fn dep_context(&self) -> &Self::DepContext {
65 &self.tcx
66 }
67}
68
69impl QueryContext for QueryCtxt<'_> {
70 #[inline]
71 fn next_job_id(self) -> QueryJobId {
72 QueryJobId(
73 NonZero::new(self.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
74 .unwrap(),
75 )
76 }
77
78 #[inline]
79 fn current_query_job(self) -> Option<QueryJobId> {
80 tls::with_related_context(self.tcx, |icx| icx.query)
81 }
82
83 fn collect_active_jobs(self) -> QueryMap {
84 let mut jobs = QueryMap::default();
85
86 for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
87 collect(self.tcx, &mut jobs);
88 }
89
90 jobs
91 }
92
93 fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects {
95 self.query_system
96 .on_disk_cache
97 .as_ref()
98 .map(|c| c.load_side_effects(self.tcx, prev_dep_node_index))
99 .unwrap_or_default()
100 }
101
102 #[inline(never)]
103 #[cold]
104 fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
105 if let Some(c) = self.query_system.on_disk_cache.as_ref() {
106 c.store_side_effects(dep_node_index, side_effects)
107 }
108 }
109
110 #[inline(never)]
111 #[cold]
112 fn store_side_effects_for_anon_node(
113 self,
114 dep_node_index: DepNodeIndex,
115 side_effects: QuerySideEffects,
116 ) {
117 if let Some(c) = self.query_system.on_disk_cache.as_ref() {
118 c.store_side_effects_for_anon_node(dep_node_index, side_effects)
119 }
120 }
121
122 #[inline(always)]
126 fn start_query<R>(
127 self,
128 token: QueryJobId,
129 depth_limit: bool,
130 diagnostics: Option<&Lock<ThinVec<DiagInner>>>,
131 compute: impl FnOnce() -> R,
132 ) -> R {
133 tls::with_related_context(self.tcx, move |current_icx| {
137 if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) {
138 self.depth_limit_error(token);
139 }
140
141 let new_icx = ImplicitCtxt {
143 tcx: self.tcx,
144 query: Some(token),
145 diagnostics,
146 query_depth: current_icx.query_depth + depth_limit as usize,
147 task_deps: current_icx.task_deps,
148 };
149
150 tls::enter_context(&new_icx, compute)
152 })
153 }
154
155 fn depth_limit_error(self, job: QueryJobId) {
156 let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
157
158 let suggested_limit = match self.recursion_limit() {
159 Limit(0) => Limit(2),
160 limit => limit * 2,
161 };
162
163 self.sess.dcx().emit_fatal(QueryOverflow {
164 span: info.job.span,
165 note: QueryOverflowNote { desc: info.query.description, depth },
166 suggested_limit,
167 crate_name: self.crate_name(LOCAL_CRATE),
168 });
169 }
170}
171
172pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool {
173 tcx.dep_graph.try_mark_green(QueryCtxt::new(tcx), dep_node).is_some()
174}
175
176pub(super) fn encode_all_query_results<'tcx>(
177 tcx: TyCtxt<'tcx>,
178 encoder: &mut CacheEncoder<'_, 'tcx>,
179 query_result_index: &mut EncodedDepNodeIndex,
180) {
181 for encode in super::ENCODE_QUERY_RESULTS.iter().copied().flatten() {
182 encode(tcx, encoder, query_result_index);
183 }
184}
185
186pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
187 if tcx.sess().opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) {
188 tcx.sess.time("query_key_hash_verify_all", || {
189 for verify in super::QUERY_KEY_HASH_VERIFY.iter() {
190 verify(tcx);
191 }
192 })
193 }
194}
195
196macro_rules! handle_cycle_error {
197 ([]) => {{
198 rustc_query_system::HandleCycleError::Error
199 }};
200 ([(fatal_cycle) $($rest:tt)*]) => {{
201 rustc_query_system::HandleCycleError::Fatal
202 }};
203 ([(cycle_stash) $($rest:tt)*]) => {{
204 rustc_query_system::HandleCycleError::Stash
205 }};
206 ([(cycle_delay_bug) $($rest:tt)*]) => {{
207 rustc_query_system::HandleCycleError::DelayBug
208 }};
209 ([$other:tt $($modifiers:tt)*]) => {
210 handle_cycle_error!([$($modifiers)*])
211 };
212}
213
214macro_rules! is_anon {
215 ([]) => {{
216 false
217 }};
218 ([(anon) $($rest:tt)*]) => {{
219 true
220 }};
221 ([$other:tt $($modifiers:tt)*]) => {
222 is_anon!([$($modifiers)*])
223 };
224}
225
226macro_rules! is_eval_always {
227 ([]) => {{
228 false
229 }};
230 ([(eval_always) $($rest:tt)*]) => {{
231 true
232 }};
233 ([$other:tt $($modifiers:tt)*]) => {
234 is_eval_always!([$($modifiers)*])
235 };
236}
237
238macro_rules! depth_limit {
239 ([]) => {{
240 false
241 }};
242 ([(depth_limit) $($rest:tt)*]) => {{
243 true
244 }};
245 ([$other:tt $($modifiers:tt)*]) => {
246 depth_limit!([$($modifiers)*])
247 };
248}
249
250macro_rules! feedable {
251 ([]) => {{
252 false
253 }};
254 ([(feedable) $($rest:tt)*]) => {{
255 true
256 }};
257 ([$other:tt $($modifiers:tt)*]) => {
258 feedable!([$($modifiers)*])
259 };
260}
261
262macro_rules! hash_result {
263 ([][$V:ty]) => {{
264 Some(|hcx, result| dep_graph::hash_result(hcx, &restore::<$V>(*result)))
265 }};
266 ([(no_hash) $($rest:tt)*][$V:ty]) => {{
267 None
268 }};
269 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
270 hash_result!([$($modifiers)*][$($args)*])
271 };
272}
273
274macro_rules! call_provider {
275 ([][$tcx:expr, $name:ident, $key:expr]) => {{
276 ($tcx.query_system.fns.local_providers.$name)($tcx, $key)
277 }};
278 ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{
279 if let Some(key) = $key.as_local_key() {
280 ($tcx.query_system.fns.local_providers.$name)($tcx, key)
281 } else {
282 ($tcx.query_system.fns.extern_providers.$name)($tcx, $key)
283 }
284 }};
285 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
286 call_provider!([$($modifiers)*][$($args)*])
287 };
288}
289
290macro_rules! should_ever_cache_on_disk {
291 ([]$yes:tt $no:tt) => {{
292 $no
293 }};
294 ([(cache) $($rest:tt)*]$yes:tt $no:tt) => {{
295 $yes
296 }};
297 ([$other:tt $($modifiers:tt)*]$yes:tt $no:tt) => {
298 should_ever_cache_on_disk!([$($modifiers)*]$yes $no)
299 };
300}
301
302pub(crate) fn create_query_frame<
303 'tcx,
304 K: Copy + Key + for<'a> HashStable<StableHashingContext<'a>>,
305>(
306 tcx: TyCtxt<'tcx>,
307 do_describe: fn(TyCtxt<'tcx>, K) -> String,
308 key: K,
309 kind: DepKind,
310 name: &'static str,
311) -> QueryStackFrame {
312 let reduce_queries = with_reduced_queries();
315
316 let description = ty::print::with_no_queries!(do_describe(tcx, key));
318 let description = if tcx.sess.verbose_internals() {
319 format!("{description} [{name:?}]")
320 } else {
321 description
322 };
323 let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries {
324 None
327 } else {
328 Some(key.default_span(tcx))
329 };
330 let def_id = key.key_as_def_id();
331 let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries {
332 None
334 } else {
335 def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id))
336 };
337 let hash = || {
338 tcx.with_stable_hashing_context(|mut hcx| {
339 let mut hasher = StableHasher::new();
340 kind.as_usize().hash_stable(&mut hcx, &mut hasher);
341 key.hash_stable(&mut hcx, &mut hasher);
342 hasher.finish::<Hash64>()
343 })
344 };
345 let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle();
346
347 QueryStackFrame::new(description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash)
348}
349
350pub(crate) fn encode_query_results<'a, 'tcx, Q>(
351 query: Q::Config,
352 qcx: QueryCtxt<'tcx>,
353 encoder: &mut CacheEncoder<'a, 'tcx>,
354 query_result_index: &mut EncodedDepNodeIndex,
355) where
356 Q: super::QueryConfigRestored<'tcx>,
357 Q::RestoredValue: Encodable<CacheEncoder<'a, 'tcx>>,
358{
359 let _timer = qcx.profiler().generic_activity_with_arg("encode_query_results_for", query.name());
360
361 assert!(query.query_state(qcx).all_inactive());
362 let cache = query.query_cache(qcx);
363 cache.iter(&mut |key, value, dep_node| {
364 if query.cache_on_disk(qcx.tcx, key) {
365 let dep_node = SerializedDepNodeIndex::new(dep_node.index());
366
367 query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
369
370 encoder.encode_tagged(dep_node, &Q::restore(*value));
373 }
374 });
375}
376
377pub(crate) fn query_key_hash_verify<'tcx>(
378 query: impl QueryConfig<QueryCtxt<'tcx>>,
379 qcx: QueryCtxt<'tcx>,
380) {
381 let _timer =
382 qcx.profiler().generic_activity_with_arg("query_key_hash_verify_for", query.name());
383
384 let mut map = UnordMap::default();
385
386 let cache = query.query_cache(qcx);
387 cache.iter(&mut |key, _, _| {
388 let node = DepNode::construct(qcx.tcx, query.dep_kind(), key);
389 if let Some(other_key) = map.insert(node, *key) {
390 bug!(
391 "query key:\n\
392 `{:?}`\n\
393 and key:\n\
394 `{:?}`\n\
395 mapped to the same dep node:\n\
396 {:?}",
397 key,
398 other_key,
399 node
400 );
401 }
402 });
403}
404
405fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode)
406where
407 Q: QueryConfig<QueryCtxt<'tcx>>,
408{
409 debug_assert!(tcx.dep_graph.is_green(&dep_node));
410
411 let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
412 panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
413 });
414 if query.cache_on_disk(tcx, &key) {
415 let _ = query.execute_query(tcx, key);
416 }
417}
418
419pub(crate) fn loadable_from_disk<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeIndex) -> bool {
420 if let Some(cache) = tcx.query_system.on_disk_cache.as_ref() {
421 cache.loadable_from_disk(id)
422 } else {
423 false
424 }
425}
426
427pub(crate) fn try_load_from_disk<'tcx, V>(
428 tcx: TyCtxt<'tcx>,
429 prev_index: SerializedDepNodeIndex,
430 index: DepNodeIndex,
431) -> Option<V>
432where
433 V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
434{
435 let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?;
436
437 let prof_timer = tcx.prof.incr_cache_loading();
438
439 let value = tcx
443 .dep_graph
444 .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index));
445
446 prof_timer.finish_with_query_invocation_id(index.into());
447
448 value
449}
450
451fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
452where
453 Q: QueryConfig<QueryCtxt<'tcx>>,
454{
455 debug_assert!(
469 dep_node.kind != dep_kinds::codegen_unit,
470 "calling force_from_dep_node() on dep_kinds::codegen_unit"
471 );
472
473 if let Some(key) = Q::Key::recover(tcx, &dep_node) {
474 force_query(query, QueryCtxt::new(tcx), key, dep_node);
475 true
476 } else {
477 false
478 }
479}
480
481pub(crate) fn query_callback<'tcx, Q>(is_anon: bool, is_eval_always: bool) -> DepKindStruct<'tcx>
482where
483 Q: QueryConfigRestored<'tcx>,
484{
485 let fingerprint_style = <Q::Config as QueryConfig<QueryCtxt<'tcx>>>::Key::fingerprint_style();
486
487 if is_anon || !fingerprint_style.reconstructible() {
488 return DepKindStruct {
489 is_anon,
490 is_eval_always,
491 fingerprint_style,
492 force_from_dep_node: None,
493 try_load_from_on_disk_cache: None,
494 name: Q::NAME,
495 };
496 }
497
498 DepKindStruct {
499 is_anon,
500 is_eval_always,
501 fingerprint_style,
502 force_from_dep_node: Some(|tcx, dep_node| {
503 force_from_dep_node(Q::config(tcx), tcx, dep_node)
504 }),
505 try_load_from_on_disk_cache: Some(|tcx, dep_node| {
506 try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node)
507 }),
508 name: Q::NAME,
509 }
510}
511
512macro_rules! item_if_cached {
513 ([] $tokens:tt) => {};
514 ([(cache) $($rest:tt)*] { $($tokens:tt)* }) => {
515 $($tokens)*
516 };
517 ([$other:tt $($modifiers:tt)*] $tokens:tt) => {
518 item_if_cached! { [$($modifiers)*] $tokens }
519 };
520}
521
522macro_rules! expand_if_cached {
523 ([], $tokens:expr) => {{
524 None
525 }};
526 ([(cache) $($rest:tt)*], $tokens:expr) => {{
527 Some($tokens)
528 }};
529 ([$other:tt $($modifiers:tt)*], $tokens:expr) => {
530 expand_if_cached!([$($modifiers)*], $tokens)
531 };
532}
533
534#[inline(never)]
537pub(crate) fn __rust_begin_short_backtrace<F, T>(f: F) -> T
538where
539 F: FnOnce() -> T,
540{
541 let result = f();
542 std::hint::black_box(());
543 result
544}
545
546macro_rules! define_queries {
549 (
550 $($(#[$attr:meta])*
551 [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
552
553 pub(crate) mod query_impl { $(pub(crate) mod $name {
554 use super::super::*;
555 use std::marker::PhantomData;
556
557 pub(crate) mod get_query_incr {
558 use super::*;
559
560 #[inline(never)]
563 pub(crate) fn __rust_end_short_backtrace<'tcx>(
564 tcx: TyCtxt<'tcx>,
565 span: Span,
566 key: queries::$name::Key<'tcx>,
567 mode: QueryMode,
568 ) -> Option<Erase<queries::$name::Value<'tcx>>> {
569 #[cfg(debug_assertions)]
570 let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
571 get_query_incr(
572 QueryType::config(tcx),
573 QueryCtxt::new(tcx),
574 span,
575 key,
576 mode
577 )
578 }
579 }
580
581 pub(crate) mod get_query_non_incr {
582 use super::*;
583
584 #[inline(never)]
585 pub(crate) fn __rust_end_short_backtrace<'tcx>(
586 tcx: TyCtxt<'tcx>,
587 span: Span,
588 key: queries::$name::Key<'tcx>,
589 __mode: QueryMode,
590 ) -> Option<Erase<queries::$name::Value<'tcx>>> {
591 Some(get_query_non_incr(
592 QueryType::config(tcx),
593 QueryCtxt::new(tcx),
594 span,
595 key,
596 ))
597 }
598 }
599
600 pub(crate) fn dynamic_query<'tcx>()
601 -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>>
602 {
603 DynamicQuery {
604 name: stringify!($name),
605 eval_always: is_eval_always!([$($modifiers)*]),
606 dep_kind: dep_graph::dep_kinds::$name,
607 handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
608 query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
609 query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
610 cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
611 execute_query: |tcx, key| erase(tcx.$name(key)),
612 compute: |tcx, key| {
613 #[cfg(debug_assertions)]
614 let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
615 __rust_begin_short_backtrace(||
616 queries::$name::provided_to_erased(
617 tcx,
618 {
619 let ret = call_provider!([$($modifiers)*][tcx, $name, key]);
620 rustc_middle::ty::print::with_reduced_queries!({
621 tracing::trace!(?ret);
622 });
623 ret
624 }
625 )
626 )
627 },
628 can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
629 try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
630 |tcx, key, prev_index, index| {
631 if ::rustc_middle::query::cached::$name(tcx, key) {
632 let value = $crate::plumbing::try_load_from_disk::<
633 queries::$name::ProvidedValue<'tcx>
634 >(
635 tcx,
636 prev_index,
637 index,
638 );
639 value.map(|value| queries::$name::provided_to_erased(tcx, value))
640 } else {
641 None
642 }
643 }
644 } {
645 |_tcx, _key, _prev_index, _index| None
646 }),
647 value_from_cycle_error: |tcx, cycle, guar| {
648 let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
649 erase(result)
650 },
651 loadable_from_disk: |_tcx, _key, _index| {
652 should_ever_cache_on_disk!([$($modifiers)*] {
653 ::rustc_middle::query::cached::$name(_tcx, _key) &&
654 $crate::plumbing::loadable_from_disk(_tcx, _index)
655 } {
656 false
657 })
658 },
659 hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
660 format_value: |value| format!("{:?}", restore::<queries::$name::Value<'tcx>>(*value)),
661 }
662 }
663
664 #[derive(Copy, Clone, Default)]
665 pub(crate) struct QueryType<'tcx> {
666 data: PhantomData<&'tcx ()>
667 }
668
669 impl<'tcx> QueryConfigRestored<'tcx> for QueryType<'tcx> {
670 type RestoredValue = queries::$name::Value<'tcx>;
671 type Config = DynamicConfig<
672 'tcx,
673 queries::$name::Storage<'tcx>,
674 { is_anon!([$($modifiers)*]) },
675 { depth_limit!([$($modifiers)*]) },
676 { feedable!([$($modifiers)*]) },
677 >;
678
679 const NAME: &'static &'static str = &stringify!($name);
680
681 #[inline(always)]
682 fn config(tcx: TyCtxt<'tcx>) -> Self::Config {
683 DynamicConfig {
684 dynamic: &tcx.query_system.dynamic_queries.$name,
685 }
686 }
687
688 #[inline(always)]
689 fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue {
690 restore::<queries::$name::Value<'tcx>>(value)
691 }
692 }
693
694 pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
695 let make_query = |tcx, key| {
696 let kind = rustc_middle::dep_graph::dep_kinds::$name;
697 let name = stringify!($name);
698 $crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name)
699 };
700 let res = tcx.query_system.states.$name.try_collect_active_jobs(
701 tcx,
702 make_query,
703 qmap,
704 );
705 if res.is_none() {
709 tracing::warn!(
710 "Failed to collect active jobs for query with name `{}`!",
711 stringify!($name)
712 );
713 }
714 }
715
716 pub(crate) fn alloc_self_profile_query_strings<'tcx>(
717 tcx: TyCtxt<'tcx>,
718 string_cache: &mut QueryKeyStringCache
719 ) {
720 $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache(
721 tcx,
722 stringify!($name),
723 &tcx.query_system.caches.$name,
724 string_cache,
725 )
726 }
727
728 item_if_cached! { [$($modifiers)*] {
729 pub(crate) fn encode_query_results<'tcx>(
730 tcx: TyCtxt<'tcx>,
731 encoder: &mut CacheEncoder<'_, 'tcx>,
732 query_result_index: &mut EncodedDepNodeIndex
733 ) {
734 $crate::plumbing::encode_query_results::<query_impl::$name::QueryType<'tcx>>(
735 query_impl::$name::QueryType::config(tcx),
736 QueryCtxt::new(tcx),
737 encoder,
738 query_result_index,
739 )
740 }
741 }}
742
743 pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
744 $crate::plumbing::query_key_hash_verify(
745 query_impl::$name::QueryType::config(tcx),
746 QueryCtxt::new(tcx),
747 )
748 }
749 })*}
750
751 pub(crate) fn engine(incremental: bool) -> QueryEngine {
752 if incremental {
753 QueryEngine {
754 $($name: query_impl::$name::get_query_incr::__rust_end_short_backtrace,)*
755 }
756 } else {
757 QueryEngine {
758 $($name: query_impl::$name::get_query_non_incr::__rust_end_short_backtrace,)*
759 }
760 }
761 }
762
763 pub fn dynamic_queries<'tcx>() -> DynamicQueries<'tcx> {
764 DynamicQueries {
765 $(
766 $name: query_impl::$name::dynamic_query(),
767 )*
768 }
769 }
770
771 const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
774 &[$(query_impl::$name::try_collect_active_jobs),*];
775
776 const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[
777 for<'tcx> fn(TyCtxt<'tcx>, &mut QueryKeyStringCache)
778 ] = &[$(query_impl::$name::alloc_self_profile_query_strings),*];
779
780 const ENCODE_QUERY_RESULTS: &[
781 Option<for<'tcx> fn(
782 TyCtxt<'tcx>,
783 &mut CacheEncoder<'_, 'tcx>,
784 &mut EncodedDepNodeIndex)
785 >
786 ] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*];
787
788 const QUERY_KEY_HASH_VERIFY: &[
789 for<'tcx> fn(TyCtxt<'tcx>)
790 ] = &[$(query_impl::$name::query_key_hash_verify),*];
791
792 #[allow(nonstandard_style)]
793 mod query_callbacks {
794 use super::*;
795 use rustc_middle::bug;
796 use rustc_query_system::dep_graph::FingerprintStyle;
797
798 pub(crate) fn Null<'tcx>() -> DepKindStruct<'tcx> {
800 DepKindStruct {
801 is_anon: false,
802 is_eval_always: false,
803 fingerprint_style: FingerprintStyle::Unit,
804 force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
805 try_load_from_on_disk_cache: None,
806 name: &"Null",
807 }
808 }
809
810 pub(crate) fn Red<'tcx>() -> DepKindStruct<'tcx> {
812 DepKindStruct {
813 is_anon: false,
814 is_eval_always: false,
815 fingerprint_style: FingerprintStyle::Unit,
816 force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
817 try_load_from_on_disk_cache: None,
818 name: &"Red",
819 }
820 }
821
822 pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
823 DepKindStruct {
824 is_anon: true,
825 is_eval_always: false,
826 fingerprint_style: FingerprintStyle::Unit,
827 force_from_dep_node: None,
828 try_load_from_on_disk_cache: None,
829 name: &"TraitSelect",
830 }
831 }
832
833 pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
834 DepKindStruct {
835 is_anon: false,
836 is_eval_always: false,
837 fingerprint_style: FingerprintStyle::Opaque,
838 force_from_dep_node: None,
839 try_load_from_on_disk_cache: None,
840 name: &"CompileCodegenUnit",
841 }
842 }
843
844 pub(crate) fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
845 DepKindStruct {
846 is_anon: false,
847 is_eval_always: false,
848 fingerprint_style: FingerprintStyle::Opaque,
849 force_from_dep_node: None,
850 try_load_from_on_disk_cache: None,
851 name: &"CompileMonoItem",
852 }
853 }
854
855 $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
856 $crate::plumbing::query_callback::<query_impl::$name::QueryType<'tcx>>(
857 is_anon!([$($modifiers)*]),
858 is_eval_always!([$($modifiers)*]),
859 )
860 })*
861 }
862
863 pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
864 arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(query_callbacks))
865 }
866 }
867}