1#![allow(internal_features)]
5#![allow(unused_parens)]
6#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
7#![doc(rust_logo)]
8#![feature(min_specialization)]
9#![feature(rustc_attrs)]
10#![feature(rustdoc_internals)]
11use rustc_data_structures::stable_hasher::HashStable;
14use rustc_data_structures::sync::AtomicU64;
15use rustc_middle::arena::Arena;
16use rustc_middle::dep_graph::{self, DepKind, DepKindStruct, DepNodeIndex};
17use rustc_middle::query::erase::{Erase, erase, restore};
18use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
19use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns};
20use rustc_middle::query::{
21 AsLocalKey, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates,
22 queries,
23};
24use rustc_middle::ty::TyCtxt;
25use rustc_query_system::dep_graph::SerializedDepNodeIndex;
26use rustc_query_system::ich::StableHashingContext;
27use rustc_query_system::query::{
28 CycleError, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode, QueryStackDeferred,
29 QueryState, get_query_incr, get_query_non_incr,
30};
31use rustc_query_system::{HandleCycleError, Value};
32use rustc_span::{ErrorGuaranteed, Span};
33
34use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green};
35use crate::profiling_support::QueryKeyStringCache;
36
37#[macro_use]
38mod plumbing;
39pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
40
41mod profiling_support;
42pub use self::profiling_support::alloc_self_profile_query_strings;
43
44struct DynamicConfig<
45 'tcx,
46 C: QueryCache,
47 const ANON: bool,
48 const DEPTH_LIMIT: bool,
49 const FEEDABLE: bool,
50> {
51 dynamic: &'tcx DynamicQuery<'tcx, C>,
52}
53
54impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy
55 for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
56{
57}
58impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone
59 for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
60{
61 fn clone(&self) -> Self {
62 DynamicConfig { dynamic: self.dynamic }
63 }
64}
65
66impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool>
67 QueryConfig<QueryCtxt<'tcx>> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
68where
69 for<'a> C::Key: HashStable<StableHashingContext<'a>>,
70{
71 type Key = C::Key;
72 type Value = C::Value;
73 type Cache = C;
74
75 #[inline(always)]
76 fn name(self) -> &'static str {
77 self.dynamic.name
78 }
79
80 #[inline(always)]
81 fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
82 (self.dynamic.cache_on_disk)(tcx, key)
83 }
84
85 #[inline(always)]
86 fn query_state<'a>(
87 self,
88 qcx: QueryCtxt<'tcx>,
89 ) -> &'a QueryState<Self::Key, QueryStackDeferred<'tcx>>
90 where
91 QueryCtxt<'tcx>: 'a,
92 {
93 unsafe {
96 &*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>)
97 .byte_add(self.dynamic.query_state)
98 .cast::<QueryState<Self::Key, QueryStackDeferred<'tcx>>>()
99 }
100 }
101
102 #[inline(always)]
103 fn query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::Cache
104 where
105 'tcx: 'a,
106 {
107 unsafe {
110 &*(&qcx.tcx.query_system.caches as *const QueryCaches<'tcx>)
111 .byte_add(self.dynamic.query_cache)
112 .cast::<Self::Cache>()
113 }
114 }
115
116 #[inline(always)]
117 fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
118 (self.dynamic.execute_query)(tcx, key)
119 }
120
121 #[inline(always)]
122 fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
123 (self.dynamic.compute)(qcx.tcx, key)
124 }
125
126 #[inline(always)]
127 fn try_load_from_disk(
128 self,
129 qcx: QueryCtxt<'tcx>,
130 key: &Self::Key,
131 prev_index: SerializedDepNodeIndex,
132 index: DepNodeIndex,
133 ) -> Option<Self::Value> {
134 if self.dynamic.can_load_from_disk {
135 (self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index)
136 } else {
137 None
138 }
139 }
140
141 #[inline]
142 fn loadable_from_disk(
143 self,
144 qcx: QueryCtxt<'tcx>,
145 key: &Self::Key,
146 index: SerializedDepNodeIndex,
147 ) -> bool {
148 (self.dynamic.loadable_from_disk)(qcx.tcx, key, index)
149 }
150
151 fn value_from_cycle_error(
152 self,
153 tcx: TyCtxt<'tcx>,
154 cycle_error: &CycleError,
155 guar: ErrorGuaranteed,
156 ) -> Self::Value {
157 (self.dynamic.value_from_cycle_error)(tcx, cycle_error, guar)
158 }
159
160 #[inline(always)]
161 fn format_value(self) -> fn(&Self::Value) -> String {
162 self.dynamic.format_value
163 }
164
165 #[inline(always)]
166 fn anon(self) -> bool {
167 ANON
168 }
169
170 #[inline(always)]
171 fn eval_always(self) -> bool {
172 self.dynamic.eval_always
173 }
174
175 #[inline(always)]
176 fn depth_limit(self) -> bool {
177 DEPTH_LIMIT
178 }
179
180 #[inline(always)]
181 fn feedable(self) -> bool {
182 FEEDABLE
183 }
184
185 #[inline(always)]
186 fn dep_kind(self) -> DepKind {
187 self.dynamic.dep_kind
188 }
189
190 #[inline(always)]
191 fn handle_cycle_error(self) -> HandleCycleError {
192 self.dynamic.handle_cycle_error
193 }
194
195 #[inline(always)]
196 fn hash_result(self) -> HashResult<Self::Value> {
197 self.dynamic.hash_result
198 }
199}
200
201trait QueryConfigRestored<'tcx> {
204 type RestoredValue;
205 type Config: QueryConfig<QueryCtxt<'tcx>>;
206
207 const NAME: &'static &'static str;
208
209 fn config(tcx: TyCtxt<'tcx>) -> Self::Config;
210 fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value)
211 -> Self::RestoredValue;
212}
213
214pub fn query_system<'a>(
215 local_providers: Providers,
216 extern_providers: ExternProviders,
217 on_disk_cache: Option<OnDiskCache>,
218 incremental: bool,
219) -> QuerySystem<'a> {
220 QuerySystem {
221 states: Default::default(),
222 arenas: Default::default(),
223 caches: Default::default(),
224 dynamic_queries: dynamic_queries(),
225 on_disk_cache,
226 fns: QuerySystemFns {
227 engine: engine(incremental),
228 local_providers,
229 extern_providers,
230 encode_query_results: encode_all_query_results,
231 try_mark_green,
232 },
233 jobs: AtomicU64::new(1),
234 }
235}
236
237rustc_middle::rustc_query_append! { define_queries! }
238
239pub fn provide(providers: &mut rustc_middle::util::Providers) {
240 providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings;
241 providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all;
242}