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