1use std::num::NonZero;
6
7use rustc_data_structures::sync::{DynSend, DynSync};
8use rustc_data_structures::unord::UnordMap;
9use rustc_hir::def_id::DefId;
10use rustc_hir::limit::Limit;
11use rustc_index::Idx;
12use rustc_middle::bug;
13#[expect(unused_imports, reason = "used by doc comments")]
14use rustc_middle::dep_graph::DepKindVTable;
15use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeIndex, DepNodeKey, SerializedDepNodeIndex};
16use rustc_middle::query::erase::{Erasable, Erased};
17use rustc_middle::query::on_disk_cache::{
18 AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex,
19};
20use rustc_middle::query::plumbing::QueryVTable;
21use rustc_middle::query::{
22 QueryCache, QueryJobId, QueryKey, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra,
23 erase,
24};
25use rustc_middle::ty::codec::TyEncoder;
26use rustc_middle::ty::print::with_reduced_queries;
27use rustc_middle::ty::tls::{self, ImplicitCtxt};
28use rustc_middle::ty::{self, TyCtxt};
29use rustc_serialize::{Decodable, Encodable};
30use rustc_span::def_id::LOCAL_CRATE;
31
32use crate::error::{QueryOverflow, QueryOverflowNote};
33use crate::execution::{all_inactive, force_query};
34use crate::job::{QueryJobMap, find_dep_kind_root};
35
36fn depth_limit_error<'tcx>(tcx: TyCtxt<'tcx>, job: QueryJobId) {
37 let job_map =
38 collect_active_jobs_from_all_queries(tcx, true).expect("failed to collect active queries");
39 let (info, depth) = find_dep_kind_root(job, job_map);
40
41 let suggested_limit = match tcx.recursion_limit() {
42 Limit(0) => Limit(2),
43 limit => limit * 2,
44 };
45
46 tcx.sess.dcx().emit_fatal(QueryOverflow {
47 span: info.job.span,
48 note: QueryOverflowNote { desc: info.frame.info.extract().description, depth },
49 suggested_limit,
50 crate_name: tcx.crate_name(LOCAL_CRATE),
51 });
52}
53
54#[inline]
55pub(crate) fn next_job_id<'tcx>(tcx: TyCtxt<'tcx>) -> QueryJobId {
56 QueryJobId(
57 NonZero::new(tcx.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
58 .unwrap(),
59 )
60}
61
62#[inline]
63pub(crate) fn current_query_job<'tcx>(tcx: TyCtxt<'tcx>) -> Option<QueryJobId> {
64 tls::with_related_context(tcx, |icx| icx.query)
65}
66
67#[inline(always)]
70pub(crate) fn start_query<'tcx, R>(
71 tcx: TyCtxt<'tcx>,
72 token: QueryJobId,
73 depth_limit: bool,
74 compute: impl FnOnce() -> R,
75) -> R {
76 tls::with_related_context(tcx, move |current_icx| {
80 if depth_limit && !tcx.recursion_limit().value_within_limit(current_icx.query_depth) {
81 depth_limit_error(tcx, token);
82 }
83
84 let new_icx = ImplicitCtxt {
86 tcx,
87 query: Some(token),
88 query_depth: current_icx.query_depth + depth_limit as usize,
89 task_deps: current_icx.task_deps,
90 };
91
92 tls::enter_context(&new_icx, compute)
94 })
95}
96
97pub fn collect_active_jobs_from_all_queries<'tcx>(
108 tcx: TyCtxt<'tcx>,
109 require_complete: bool,
110) -> Result<QueryJobMap<'tcx>, QueryJobMap<'tcx>> {
111 let mut job_map_out = QueryJobMap::default();
112 let mut complete = true;
113
114 for gather_fn in crate::PER_QUERY_GATHER_ACTIVE_JOBS_FNS.iter() {
115 if gather_fn(tcx, require_complete, &mut job_map_out).is_none() {
116 complete = false;
117 }
118 }
119
120 if complete { Ok(job_map_out) } else { Err(job_map_out) }
121}
122
123pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool {
124 tcx.dep_graph.try_mark_green(tcx, dep_node).is_some()
125}
126
127pub(super) fn encode_all_query_results<'tcx>(
128 tcx: TyCtxt<'tcx>,
129 encoder: &mut CacheEncoder<'_, 'tcx>,
130 query_result_index: &mut EncodedDepNodeIndex,
131) {
132 for encode in super::ENCODE_QUERY_RESULTS.iter().copied().flatten() {
133 encode(tcx, encoder, query_result_index);
134 }
135}
136
137pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
138 if tcx.sess.opts.unstable_opts.incremental_verify_ich || truecfg!(debug_assertions) {
139 tcx.sess.time("query_key_hash_verify_all", || {
140 for verify in super::QUERY_KEY_HASH_VERIFY.iter() {
141 verify(tcx);
142 }
143 })
144 }
145}
146
147macro_rules! cycle_error_handling {
148 ([]) => {{
149 rustc_middle::query::CycleErrorHandling::Error
150 }};
151 ([(cycle_fatal) $($rest:tt)*]) => {{
152 rustc_middle::query::CycleErrorHandling::Fatal
153 }};
154 ([(cycle_stash) $($rest:tt)*]) => {{
155 rustc_middle::query::CycleErrorHandling::Stash
156 }};
157 ([(cycle_delay_bug) $($rest:tt)*]) => {{
158 rustc_middle::query::CycleErrorHandling::DelayBug
159 }};
160 ([$other:tt $($modifiers:tt)*]) => {
161 cycle_error_handling!([$($modifiers)*])
162 };
163}
164
165macro_rules! is_anon {
166 ([]) => {{
167 false
168 }};
169 ([(anon) $($rest:tt)*]) => {{
170 true
171 }};
172 ([$other:tt $($modifiers:tt)*]) => {
173 is_anon!([$($modifiers)*])
174 };
175}
176
177macro_rules! is_eval_always {
178 ([]) => {{
179 false
180 }};
181 ([(eval_always) $($rest:tt)*]) => {{
182 true
183 }};
184 ([$other:tt $($modifiers:tt)*]) => {
185 is_eval_always!([$($modifiers)*])
186 };
187}
188
189macro_rules! is_depth_limit {
190 ([]) => {{
191 false
192 }};
193 ([(depth_limit) $($rest:tt)*]) => {{
194 true
195 }};
196 ([$other:tt $($modifiers:tt)*]) => {
197 is_depth_limit!([$($modifiers)*])
198 };
199}
200
201macro_rules! is_feedable {
202 ([]) => {{
203 false
204 }};
205 ([(feedable) $($rest:tt)*]) => {{
206 true
207 }};
208 ([$other:tt $($modifiers:tt)*]) => {
209 is_feedable!([$($modifiers)*])
210 };
211}
212
213macro_rules! hash_result {
214 ([][$V:ty]) => {{
215 Some(|hcx, result| {
216 let result = rustc_middle::query::erase::restore_val::<$V>(*result);
217 rustc_middle::dep_graph::hash_result(hcx, &result)
218 })
219 }};
220 ([(no_hash) $($rest:tt)*][$V:ty]) => {{
221 None
222 }};
223 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
224 hash_result!([$($modifiers)*][$($args)*])
225 };
226}
227
228macro_rules! call_provider {
229 ([][$tcx:expr, $name:ident, $key:expr]) => {{
230 ($tcx.query_system.local_providers.$name)($tcx, $key)
231 }};
232 ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{
233 if let Some(key) = $key.as_local_key() {
234 ($tcx.query_system.local_providers.$name)($tcx, key)
235 } else {
236 ($tcx.query_system.extern_providers.$name)($tcx, $key)
237 }
238 }};
239 ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
240 call_provider!([$($modifiers)*][$($args)*])
241 };
242}
243
244macro_rules! if_cache_on_disk {
247 ([] $yes:tt $no:tt) => {
248 $no
249 };
250 ([(cache_on_disk) $($rest:tt)*] $yes:tt $no:tt) => {
253 $yes
254 };
255 ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => {
256 if_cache_on_disk!([$($modifiers)*] $yes $no)
257 };
258}
259
260macro_rules! item_if_cache_on_disk {
263 ([] $($item:tt)*) => {};
264 ([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => {
265 $($item)*
266 };
267 ([$other:tt $($modifiers:tt)*] $($item:tt)*) => {
268 item_if_cache_on_disk! { [$($modifiers)*] $($item)* }
269 };
270}
271
272fn mk_query_stack_frame_extra<'tcx, Cache>(
274 (tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key),
275) -> QueryStackFrameExtra
276where
277 Cache: QueryCache,
278 Cache::Key: QueryKey,
279{
280 let def_id = key.key_as_def_id();
281
282 let reduce_queries = with_reduced_queries();
285
286 let description = {
{
let _guard = ReducedQueriesGuard::new();
{
let _guard = ForcedImplGuard::new();
{
let _guard = NoTrimmedGuard::new();
{
let _guard = NoVisibleGuard::new();
(vtable.description_fn)(tcx, key)
}
}
}
}
}ty::print::with_no_queries!((vtable.description_fn)(tcx, key));
288 let description = if tcx.sess.verbose_internals() {
289 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{1} [{0:?}]", vtable.name,
description))
})format!("{description} [{name:?}]", name = vtable.name)
290 } else {
291 description
292 };
293 let span = if vtable.dep_kind == DepKind::def_span || reduce_queries {
294 None
297 } else {
298 Some(key.default_span(tcx))
299 };
300
301 let def_kind = if vtable.dep_kind == DepKind::def_kind || reduce_queries {
302 None
304 } else {
305 def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id))
306 };
307 QueryStackFrameExtra::new(description, span, def_kind)
308}
309
310pub(crate) fn create_deferred_query_stack_frame<'tcx, C>(
311 tcx: TyCtxt<'tcx>,
312 vtable: &'tcx QueryVTable<'tcx, C>,
313 key: C::Key,
314) -> QueryStackFrame<QueryStackDeferred<'tcx>>
315where
316 C: QueryCache,
317 C::Key: QueryKey + DynSend + DynSync,
318 QueryVTable<'tcx, C>: DynSync,
319{
320 let kind = vtable.dep_kind;
321
322 let def_id: Option<DefId> = key.key_as_def_id();
323 let def_id_for_ty_in_cycle: Option<DefId> = key.def_id_for_ty_in_cycle();
324
325 let info = QueryStackDeferred::new((tcx, vtable, key), mk_query_stack_frame_extra);
326 QueryStackFrame::new(info, kind, def_id, def_id_for_ty_in_cycle)
327}
328
329pub(crate) fn encode_query_results_inner<'a, 'tcx, C, V>(
330 tcx: TyCtxt<'tcx>,
331 query: &'tcx QueryVTable<'tcx, C>,
332 encoder: &mut CacheEncoder<'a, 'tcx>,
333 query_result_index: &mut EncodedDepNodeIndex,
334) where
335 C: QueryCache<Value = Erased<V>>,
336 V: Erasable + Encodable<CacheEncoder<'a, 'tcx>>,
337{
338 let _timer = tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name);
339
340 if !all_inactive(&query.state) {
::core::panicking::panic("assertion failed: all_inactive(&query.state)")
};assert!(all_inactive(&query.state));
341 query.cache.iter(&mut |key, value, dep_node| {
342 if query.will_cache_on_disk_for_key(tcx, key) {
343 let dep_node = SerializedDepNodeIndex::new(dep_node.index());
344
345 query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
347
348 encoder.encode_tagged(dep_node, &erase::restore_val::<V>(*value));
351 }
352 });
353}
354
355pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache>(
356 query: &'tcx QueryVTable<'tcx, C>,
357 tcx: TyCtxt<'tcx>,
358) {
359 let _timer = tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name);
360
361 let cache = &query.cache;
362 let mut map = UnordMap::with_capacity(cache.len());
363 cache.iter(&mut |key, _, _| {
364 let node = DepNode::construct(tcx, query.dep_kind, key);
365 if let Some(other_key) = map.insert(node, *key) {
366 ::rustc_middle::util::bug::bug_fmt(format_args!("query key:\n`{0:?}`\nand key:\n`{1:?}`\nmapped to the same dep node:\n{2:?}",
key, other_key, node));bug!(
367 "query key:\n\
368 `{:?}`\n\
369 and key:\n\
370 `{:?}`\n\
371 mapped to the same dep node:\n\
372 {:?}",
373 key,
374 other_key,
375 node
376 );
377 }
378 });
379}
380
381pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache>(
383 query: &'tcx QueryVTable<'tcx, C>,
384 tcx: TyCtxt<'tcx>,
385 dep_node: DepNode,
386) {
387 if true {
if !tcx.dep_graph.is_green(&dep_node) {
::core::panicking::panic("assertion failed: tcx.dep_graph.is_green(&dep_node)")
};
};debug_assert!(tcx.dep_graph.is_green(&dep_node));
388
389 let key = C::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| {
390 {
::core::panicking::panic_fmt(format_args!("Failed to recover key for {1:?} with key fingerprint {0}",
dep_node.key_fingerprint, dep_node));
}panic!(
391 "Failed to recover key for {dep_node:?} with key fingerprint {}",
392 dep_node.key_fingerprint
393 )
394 });
395 if query.will_cache_on_disk_for_key(tcx, &key) {
396 (query.call_query_method_fn)(tcx, key);
399 }
400}
401
402pub(crate) fn loadable_from_disk<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeIndex) -> bool {
403 if let Some(cache) = tcx.query_system.on_disk_cache.as_ref() {
404 cache.loadable_from_disk(id)
405 } else {
406 false
407 }
408}
409
410pub(crate) fn try_load_from_disk<'tcx, V>(
411 tcx: TyCtxt<'tcx>,
412 prev_index: SerializedDepNodeIndex,
413 index: DepNodeIndex,
414) -> Option<V>
415where
416 V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
417{
418 let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?;
419
420 let prof_timer = tcx.prof.incr_cache_loading();
421
422 let value = tcx
426 .dep_graph
427 .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index));
428
429 prof_timer.finish_with_query_invocation_id(index.into());
430
431 value
432}
433
434pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache>(
436 query: &'tcx QueryVTable<'tcx, C>,
437 tcx: TyCtxt<'tcx>,
438 dep_node: DepNode,
439) -> bool {
440 if true {
if !(dep_node.kind != DepKind::codegen_unit) {
{
::core::panicking::panic_fmt(format_args!("calling force_from_dep_node() on dep_kinds::codegen_unit"));
}
};
};debug_assert!(
454 dep_node.kind != DepKind::codegen_unit,
455 "calling force_from_dep_node() on dep_kinds::codegen_unit"
456 );
457
458 if let Some(key) = C::Key::try_recover_key(tcx, &dep_node) {
459 force_query(query, tcx, key, dep_node);
460 true
461 } else {
462 false
463 }
464}
465
466macro_rules! define_queries {
468 (
469 $(
470 $(#[$attr:meta])*
471 [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,
472 )*
473 ) => {
474
475 pub(crate) mod query_impl { $(pub(crate) mod $name {
476 use super::super::*;
477 use ::rustc_middle::query::erase::{self, Erased};
478
479 pub(crate) mod execute_query_incr {
485 use super::*;
486
487 #[inline(never)]
490 pub(crate) fn __rust_end_short_backtrace<'tcx>(
491 tcx: TyCtxt<'tcx>,
492 span: Span,
493 key: queries::$name::Key<'tcx>,
494 mode: QueryMode,
495 ) -> Option<Erased<queries::$name::Value<'tcx>>> {
496 #[cfg(debug_assertions)]
497 let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
498 execution::execute_query_incr_inner(
499 &tcx.query_system.query_vtables.$name,
500 tcx,
501 span,
502 key,
503 mode
504 )
505 }
506 }
507
508 pub(crate) mod execute_query_non_incr {
509 use super::*;
510
511 #[inline(never)]
512 pub(crate) fn __rust_end_short_backtrace<'tcx>(
513 tcx: TyCtxt<'tcx>,
514 span: Span,
515 key: queries::$name::Key<'tcx>,
516 __mode: QueryMode,
517 ) -> Option<Erased<queries::$name::Value<'tcx>>> {
518 Some(execution::execute_query_non_incr_inner(
519 &tcx.query_system.query_vtables.$name,
520 tcx,
521 span,
522 key,
523 ))
524 }
525 }
526
527 mod invoke_provider_fn {
533 use super::*;
534 use ::rustc_middle::queries::$name::{Key, Value, provided_to_erased};
535
536 #[inline(never)]
537 pub(crate) fn __rust_begin_short_backtrace<'tcx>(
538 tcx: TyCtxt<'tcx>,
539 key: Key<'tcx>,
540 ) -> Erased<Value<'tcx>> {
541 #[cfg(debug_assertions)]
542 let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
543
544 let provided_value = call_provider!([$($modifiers)*][tcx, $name, key]);
546
547 rustc_middle::ty::print::with_reduced_queries!({
548 tracing::trace!(?provided_value);
549 });
550
551 provided_to_erased(tcx, provided_value)
554 }
555 }
556
557 pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
558 -> QueryVTable<'tcx, queries::$name::Cache<'tcx>>
559 {
560 QueryVTable {
561 name: stringify!($name),
562 anon: is_anon!([$($modifiers)*]),
563 eval_always: is_eval_always!([$($modifiers)*]),
564 depth_limit: is_depth_limit!([$($modifiers)*]),
565 feedable: is_feedable!([$($modifiers)*]),
566 dep_kind: dep_graph::DepKind::$name,
567 cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
568 state: Default::default(),
569 cache: Default::default(),
570 will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] {
571 Some(::rustc_middle::queries::_cache_on_disk_if_fns::$name)
572 } {
573 None
574 }),
575 call_query_method_fn: |tcx, key| {
576 let _ = tcx.$name(key);
579 },
580 invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace,
581 try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
582 Some(|tcx, key, prev_index, index| {
583 if !::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) {
585 return None;
586 }
587
588 let value: queries::$name::ProvidedValue<'tcx> =
589 $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?;
590
591 Some(queries::$name::provided_to_erased(tcx, value))
593 })
594 } {
595 None
596 }),
597 is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
598 Some(|tcx, key, index| -> bool {
599 ::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
600 $crate::plumbing::loadable_from_disk(tcx, index)
601 })
602 } {
603 None
604 }),
605 value_from_cycle_error: |tcx, cycle, guar| {
606 let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
607 erase::erase_val(result)
608 },
609 hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
610 format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
611 description_fn: $crate::queries::_description_fns::$name,
612 execute_query_fn: if incremental {
613 query_impl::$name::execute_query_incr::__rust_end_short_backtrace
614 } else {
615 query_impl::$name::execute_query_non_incr::__rust_end_short_backtrace
616 },
617 }
618 }
619
620 pub(crate) enum VTableGetter {}
622
623 impl<'tcx> GetQueryVTable<'tcx> for VTableGetter {
624 type Cache = rustc_middle::queries::$name::Cache<'tcx>;
625
626 #[inline(always)]
627 fn query_vtable(tcx: TyCtxt<'tcx>) -> &'tcx QueryVTable<'tcx, Self::Cache> {
628 &tcx.query_system.query_vtables.$name
629 }
630 }
631
632 pub(crate) fn gather_active_jobs<'tcx>(
636 tcx: TyCtxt<'tcx>,
637 require_complete: bool,
638 job_map_out: &mut QueryJobMap<'tcx>,
639 ) -> Option<()> {
640 let make_frame = |tcx: TyCtxt<'tcx>, key| {
641 let vtable = &tcx.query_system.query_vtables.$name;
642 $crate::plumbing::create_deferred_query_stack_frame(tcx, vtable, key)
643 };
644
645 let res = crate::execution::gather_active_jobs_inner(
647 &tcx.query_system.query_vtables.$name.state,
648 tcx,
649 make_frame,
650 require_complete,
651 job_map_out,
652 );
653
654 if res.is_none() {
658 tracing::warn!(
659 "Failed to collect active jobs for query with name `{}`!",
660 stringify!($name)
661 );
662 }
663 res
664 }
665
666 pub(crate) fn alloc_self_profile_query_strings<'tcx>(
667 tcx: TyCtxt<'tcx>,
668 string_cache: &mut QueryKeyStringCache
669 ) {
670 $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache(
671 tcx,
672 stringify!($name),
673 &tcx.query_system.query_vtables.$name.cache,
674 string_cache,
675 )
676 }
677
678 item_if_cache_on_disk! { [$($modifiers)*]
679 pub(crate) fn encode_query_results<'tcx>(
680 tcx: TyCtxt<'tcx>,
681 encoder: &mut CacheEncoder<'_, 'tcx>,
682 query_result_index: &mut EncodedDepNodeIndex
683 ) {
684 $crate::plumbing::encode_query_results_inner(
685 tcx,
686 &tcx.query_system.query_vtables.$name,
687 encoder,
688 query_result_index,
689 )
690 }
691 }
692
693 pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
694 $crate::plumbing::query_key_hash_verify(
695 &tcx.query_system.query_vtables.$name,
696 tcx,
697 )
698 }
699 })*}
700
701 pub fn make_query_vtables<'tcx>(incremental: bool) -> queries::QueryVTables<'tcx> {
702 queries::QueryVTables {
703 $(
704 $name: query_impl::$name::make_query_vtable(incremental),
705 )*
706 }
707 }
708
709 const PER_QUERY_GATHER_ACTIVE_JOBS_FNS: &[
718 for<'tcx> fn(
719 tcx: TyCtxt<'tcx>,
720 require_complete: bool,
721 job_map_out: &mut QueryJobMap<'tcx>,
722 ) -> Option<()>
723 ] = &[
724 $( $crate::query_impl::$name::gather_active_jobs ),*
725 ];
726
727 const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[
728 for<'tcx> fn(TyCtxt<'tcx>, &mut QueryKeyStringCache)
729 ] = &[$(query_impl::$name::alloc_self_profile_query_strings),*];
730
731 const ENCODE_QUERY_RESULTS: &[
732 Option<for<'tcx> fn(
733 TyCtxt<'tcx>,
734 &mut CacheEncoder<'_, 'tcx>,
735 &mut EncodedDepNodeIndex)
736 >
737 ] = &[
738 $(
739 if_cache_on_disk!([$($modifiers)*] {
740 Some(query_impl::$name::encode_query_results)
741 } {
742 None
743 })
744 ),*
745 ];
746
747 const QUERY_KEY_HASH_VERIFY: &[
748 for<'tcx> fn(TyCtxt<'tcx>)
749 ] = &[$(query_impl::$name::query_key_hash_verify),*];
750
751 mod _dep_kind_vtable_ctors_for_queries {
753 use ::rustc_middle::dep_graph::DepKindVTable;
754 use $crate::dep_kind_vtables::make_dep_kind_vtable_for_query;
755
756 $(
757 pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
759 use $crate::query_impl::$name::VTableGetter;
760 make_dep_kind_vtable_for_query::<VTableGetter>(
761 is_anon!([$($modifiers)*]),
762 is_eval_always!([$($modifiers)*]),
763 )
764 }
765 )*
766 }
767 }
768}