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