1use rustc_data_structures::fingerprint::Fingerprint;
2use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
3use rustc_hir::definitions::DefPathHash;
4use rustc_hir::{HirId, ItemLocalId, OwnerId};
5pub use rustc_query_system::dep_graph::DepNode;
6use rustc_query_system::dep_graph::FingerprintStyle;
7pub use rustc_query_system::dep_graph::dep_node::DepKind;
8pub(crate) use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
9use rustc_span::Symbol;
10
11use crate::mir::mono::MonoItem;
12use crate::ty::TyCtxt;
13
14macro_rules! define_dep_nodes {
15 (
16 $(
17 $(#[$attr:meta])*
18 [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,
19 )*
20 ) => {
21
22 #[macro_export]
23 macro_rules! make_dep_kind_array {
24 ($mod:ident) => {[ $($mod::$variant()),* ]};
25 }
26
27 #[macro_export]
28 macro_rules! make_dep_kind_name_array {
29 ($mod:ident) => {
30 vec! {
31 $(*$mod::$variant().name),*
32 }
33 };
34 }
35
36 #[allow(non_camel_case_types)]
42 #[repr(u16)] enum DepKindDefs {
44 $( $( #[$attr] )* $variant),*
45 }
46
47 #[allow(non_upper_case_globals)]
48 pub mod dep_kinds {
49 use super::*;
50
51 $(
52 pub const $variant: DepKind = DepKind::new(DepKindDefs::$variant as u16);
54 )*
55 }
56
57 pub(crate) const DEP_KIND_VARIANTS: u16 = {
60 let deps = &[$(dep_kinds::$variant,)*];
61 let mut i = 0;
62 while i < deps.len() {
63 if i != deps[i].as_usize() {
64 panic!();
65 }
66 i += 1;
67 }
68 deps.len() as u16
69 };
70
71 pub(super) fn dep_kind_from_label_string(label: &str) -> Result<DepKind, ()> {
72 match label {
73 $(stringify!($variant) => Ok(dep_kinds::$variant),)*
74 _ => Err(()),
75 }
76 }
77
78 #[allow(dead_code, non_upper_case_globals)]
81 pub mod label_strs {
82 $(
83 pub const $variant: &str = stringify!($variant);
84 )*
85 }
86 };
87}
88
89rustc_with_all_queries!(define_dep_nodes![
92 [] fn Null() -> (),
94 [] fn Red() -> (),
96 [] fn SideEffect() -> (),
97 [] fn AnonZeroDeps() -> (),
98 [] fn TraitSelect() -> (),
99 [] fn CompileCodegenUnit() -> (),
100 [] fn CompileMonoItem() -> (),
101 [] fn Metadata() -> (),
102]);
103
104pub(crate) fn make_compile_codegen_unit(tcx: TyCtxt<'_>, name: Symbol) -> DepNode {
107 DepNode::construct(tcx, dep_kinds::CompileCodegenUnit, &name)
108}
109
110pub(crate) fn make_compile_mono_item<'tcx>(
113 tcx: TyCtxt<'tcx>,
114 mono_item: &MonoItem<'tcx>,
115) -> DepNode {
116 DepNode::construct(tcx, dep_kinds::CompileMonoItem, mono_item)
117}
118
119pub(crate) fn make_metadata(tcx: TyCtxt<'_>) -> DepNode {
122 DepNode::construct(tcx, dep_kinds::Metadata, &())
123}
124
125pub trait DepNodeExt: Sized {
126 fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>;
127
128 fn from_label_string(
129 tcx: TyCtxt<'_>,
130 label: &str,
131 def_path_hash: DefPathHash,
132 ) -> Result<Self, ()>;
133
134 fn has_label_string(label: &str) -> bool;
135}
136
137impl DepNodeExt for DepNode {
138 fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
149 if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
150 tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
151 } else {
152 None
153 }
154 }
155
156 fn from_label_string(
158 tcx: TyCtxt<'_>,
159 label: &str,
160 def_path_hash: DefPathHash,
161 ) -> Result<DepNode, ()> {
162 let kind = dep_kind_from_label_string(label)?;
163
164 match tcx.fingerprint_style(kind) {
165 FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
166 FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
167 FingerprintStyle::DefPathHash => {
168 Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
169 }
170 }
171 }
172
173 fn has_label_string(label: &str) -> bool {
175 dep_kind_from_label_string(label).is_ok()
176 }
177}
178
179impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for () {
180 #[inline(always)]
181 fn fingerprint_style() -> FingerprintStyle {
182 FingerprintStyle::Unit
183 }
184
185 #[inline(always)]
186 fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
187 Fingerprint::ZERO
188 }
189
190 #[inline(always)]
191 fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
192 Some(())
193 }
194}
195
196impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId {
197 #[inline(always)]
198 fn fingerprint_style() -> FingerprintStyle {
199 FingerprintStyle::DefPathHash
200 }
201
202 #[inline(always)]
203 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
204 tcx.def_path_hash(*self).0
205 }
206
207 #[inline(always)]
208 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
209 tcx.def_path_str(*self)
210 }
211
212 #[inline(always)]
213 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
214 dep_node.extract_def_id(tcx)
215 }
216}
217
218impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId {
219 #[inline(always)]
220 fn fingerprint_style() -> FingerprintStyle {
221 FingerprintStyle::DefPathHash
222 }
223
224 #[inline(always)]
225 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
226 self.to_def_id().to_fingerprint(tcx)
227 }
228
229 #[inline(always)]
230 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
231 self.to_def_id().to_debug_str(tcx)
232 }
233
234 #[inline(always)]
235 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
236 dep_node.extract_def_id(tcx).map(|id| id.expect_local())
237 }
238}
239
240impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for OwnerId {
241 #[inline(always)]
242 fn fingerprint_style() -> FingerprintStyle {
243 FingerprintStyle::DefPathHash
244 }
245
246 #[inline(always)]
247 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
248 self.to_def_id().to_fingerprint(tcx)
249 }
250
251 #[inline(always)]
252 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
253 self.to_def_id().to_debug_str(tcx)
254 }
255
256 #[inline(always)]
257 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
258 dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
259 }
260}
261
262impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
263 #[inline(always)]
264 fn fingerprint_style() -> FingerprintStyle {
265 FingerprintStyle::DefPathHash
266 }
267
268 #[inline(always)]
269 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
270 let def_id = self.as_def_id();
271 def_id.to_fingerprint(tcx)
272 }
273
274 #[inline(always)]
275 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
276 tcx.crate_name(*self).to_string()
277 }
278
279 #[inline(always)]
280 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
281 dep_node.extract_def_id(tcx).map(|id| id.krate)
282 }
283}
284
285impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
286 #[inline(always)]
287 fn fingerprint_style() -> FingerprintStyle {
288 FingerprintStyle::Opaque
289 }
290
291 #[inline(always)]
295 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
296 let (def_id_0, def_id_1) = *self;
297
298 let def_path_hash_0 = tcx.def_path_hash(def_id_0);
299 let def_path_hash_1 = tcx.def_path_hash(def_id_1);
300
301 def_path_hash_0.0.combine(def_path_hash_1.0)
302 }
303
304 #[inline(always)]
305 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
306 let (def_id_0, def_id_1) = *self;
307
308 format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1))
309 }
310}
311
312impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
313 #[inline(always)]
314 fn fingerprint_style() -> FingerprintStyle {
315 FingerprintStyle::HirId
316 }
317
318 #[inline(always)]
322 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
323 let HirId { owner, local_id } = *self;
324 let def_path_hash = tcx.def_path_hash(owner.to_def_id());
325 Fingerprint::new(
326 def_path_hash.local_hash(),
328 local_id.as_u32() as u64,
329 )
330 }
331
332 #[inline(always)]
333 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
334 let HirId { owner, local_id } = *self;
335 format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32())
336 }
337
338 #[inline(always)]
339 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
340 if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
341 let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
342 let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
343 let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
344 let local_id = local_id
345 .as_u64()
346 .try_into()
347 .unwrap_or_else(|_| panic!("local id should be u32, found {local_id:?}"));
348 Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
349 } else {
350 None
351 }
352 }
353}
354
355impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for ModDefId {
356 #[inline(always)]
357 fn fingerprint_style() -> FingerprintStyle {
358 FingerprintStyle::DefPathHash
359 }
360
361 #[inline(always)]
362 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
363 self.to_def_id().to_fingerprint(tcx)
364 }
365
366 #[inline(always)]
367 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
368 self.to_def_id().to_debug_str(tcx)
369 }
370
371 #[inline(always)]
372 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
373 DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
374 }
375}
376
377impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalModDefId {
378 #[inline(always)]
379 fn fingerprint_style() -> FingerprintStyle {
380 FingerprintStyle::DefPathHash
381 }
382
383 #[inline(always)]
384 fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
385 self.to_def_id().to_fingerprint(tcx)
386 }
387
388 #[inline(always)]
389 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
390 self.to_def_id().to_debug_str(tcx)
391 }
392
393 #[inline(always)]
394 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
395 LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
396 }
397}