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