|
1 | | -//! Nodes in the dependency graph. |
2 | | -//! |
3 | | -//! A node in the [dependency graph] is represented by a [`DepNode`]. |
4 | | -//! A `DepNode` consists of a [`DepKind`] (which |
5 | | -//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.) |
6 | | -//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which |
7 | | -//! depends on the node's `DepKind`. Together, the kind and the fingerprint |
8 | | -//! fully identify a dependency node, even across multiple compilation sessions. |
9 | | -//! In other words, the value of the fingerprint does not depend on anything |
10 | | -//! that is specific to a given compilation session, like an unpredictable |
11 | | -//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a |
12 | | -//! pointer. The concept behind this could be compared to how git commit hashes |
13 | | -//! uniquely identify a given commit. The fingerprinting approach has |
14 | | -//! a few advantages: |
15 | | -//! |
16 | | -//! * A `DepNode` can simply be serialized to disk and loaded in another session |
17 | | -//! without the need to do any "rebasing" (like we have to do for Spans and |
18 | | -//! NodeIds) or "retracing" (like we had to do for `DefId` in earlier |
19 | | -//! implementations of the dependency graph). |
20 | | -//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to |
21 | | -//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc. |
22 | | -//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into |
23 | | -//! memory without any post-processing (e.g., "abomination-style" pointer |
24 | | -//! reconstruction). |
25 | | -//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that |
26 | | -//! refer to things that do not exist anymore. In previous implementations |
27 | | -//! `DepNode` contained a `DefId`. A `DepNode` referring to something that |
28 | | -//! had been removed between the previous and the current compilation session |
29 | | -//! could not be instantiated because the current compilation session |
30 | | -//! contained no `DefId` for thing that had been removed. |
31 | | -//! |
32 | | -//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro |
33 | | -//! defines the `DepKind` enum. Each `DepKind` has its own parameters that are |
34 | | -//! needed at runtime in order to construct a valid `DepNode` fingerprint. |
35 | | -//! However, only `CompileCodegenUnit` and `CompileMonoItem` are constructed |
36 | | -//! explicitly (with `make_compile_codegen_unit` cq `make_compile_mono_item`). |
37 | | -//! |
38 | | -//! Because the macro sees what parameters a given `DepKind` requires, it can |
39 | | -//! "infer" some properties for each kind of `DepNode`: |
40 | | -//! |
41 | | -//! * Whether a `DepNode` of a given kind has any parameters at all. Some |
42 | | -//! `DepNode`s could represent global concepts with only one value. |
43 | | -//! * Whether it is possible, in principle, to reconstruct a query key from a |
44 | | -//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter, |
45 | | -//! in which case it is possible to map the node's fingerprint back to the |
46 | | -//! `DefId` it was computed from. In other cases, too much information gets |
47 | | -//! lost during fingerprint computation. |
48 | | -//! |
49 | | -//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with |
50 | | -//! `DepNode::new()`, ensures that only valid `DepNode` instances can be |
51 | | -//! constructed. For example, the API does not allow for constructing |
52 | | -//! parameterless `DepNode`s with anything other than a zeroed out fingerprint. |
53 | | -//! More generally speaking, it relieves the user of the `DepNode` API of |
54 | | -//! having to know how to compute the expected fingerprint for a given set of |
55 | | -//! node parameters. |
56 | | -//! |
57 | | -//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html |
58 | | -
|
59 | 1 | use rustc_data_structures::fingerprint::Fingerprint; |
60 | 2 | use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; |
61 | 3 | use rustc_hir::definitions::DefPathHash; |
@@ -158,26 +100,14 @@ pub(crate) fn make_compile_mono_item<'tcx>( |
158 | 100 | } |
159 | 101 |
|
160 | 102 | pub trait DepNodeExt: Sized { |
161 | | - /// Extracts the DefId corresponding to this DepNode. This will work |
162 | | - /// if two conditions are met: |
163 | | - /// |
164 | | - /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and |
165 | | - /// 2. the item that the DefPath refers to exists in the current tcx. |
166 | | - /// |
167 | | - /// Condition (1) is determined by the DepKind variant of the |
168 | | - /// DepNode. Condition (2) might not be fulfilled if a DepNode |
169 | | - /// refers to something from the previous compilation session that |
170 | | - /// has been removed. |
171 | 103 | fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>; |
172 | 104 |
|
173 | | - /// Used in testing |
174 | 105 | fn from_label_string( |
175 | 106 | tcx: TyCtxt<'_>, |
176 | 107 | label: &str, |
177 | 108 | def_path_hash: DefPathHash, |
178 | 109 | ) -> Result<Self, ()>; |
179 | 110 |
|
180 | | - /// Used in testing |
181 | 111 | fn has_label_string(label: &str) -> bool; |
182 | 112 | } |
183 | 113 |
|
@@ -399,52 +329,46 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { |
399 | 329 | } |
400 | 330 | } |
401 | 331 |
|
402 | | -macro_rules! impl_for_typed_def_id { |
403 | | - ($Name:ident, $LocalName:ident) => { |
404 | | - impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $Name { |
405 | | - #[inline(always)] |
406 | | - fn fingerprint_style() -> FingerprintStyle { |
407 | | - FingerprintStyle::DefPathHash |
408 | | - } |
| 332 | +impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for ModDefId { |
| 333 | + #[inline(always)] |
| 334 | + fn fingerprint_style() -> FingerprintStyle { |
| 335 | + FingerprintStyle::DefPathHash |
| 336 | + } |
409 | 337 |
|
410 | | - #[inline(always)] |
411 | | - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { |
412 | | - self.to_def_id().to_fingerprint(tcx) |
413 | | - } |
| 338 | + #[inline(always)] |
| 339 | + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { |
| 340 | + self.to_def_id().to_fingerprint(tcx) |
| 341 | + } |
414 | 342 |
|
415 | | - #[inline(always)] |
416 | | - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { |
417 | | - self.to_def_id().to_debug_str(tcx) |
418 | | - } |
| 343 | + #[inline(always)] |
| 344 | + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { |
| 345 | + self.to_def_id().to_debug_str(tcx) |
| 346 | + } |
419 | 347 |
|
420 | | - #[inline(always)] |
421 | | - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { |
422 | | - DefId::recover(tcx, dep_node).map($Name::new_unchecked) |
423 | | - } |
424 | | - } |
| 348 | + #[inline(always)] |
| 349 | + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { |
| 350 | + DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked) |
| 351 | + } |
| 352 | +} |
425 | 353 |
|
426 | | - impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $LocalName { |
427 | | - #[inline(always)] |
428 | | - fn fingerprint_style() -> FingerprintStyle { |
429 | | - FingerprintStyle::DefPathHash |
430 | | - } |
| 354 | +impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalModDefId { |
| 355 | + #[inline(always)] |
| 356 | + fn fingerprint_style() -> FingerprintStyle { |
| 357 | + FingerprintStyle::DefPathHash |
| 358 | + } |
431 | 359 |
|
432 | | - #[inline(always)] |
433 | | - fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { |
434 | | - self.to_def_id().to_fingerprint(tcx) |
435 | | - } |
| 360 | + #[inline(always)] |
| 361 | + fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { |
| 362 | + self.to_def_id().to_fingerprint(tcx) |
| 363 | + } |
436 | 364 |
|
437 | | - #[inline(always)] |
438 | | - fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { |
439 | | - self.to_def_id().to_debug_str(tcx) |
440 | | - } |
| 365 | + #[inline(always)] |
| 366 | + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { |
| 367 | + self.to_def_id().to_debug_str(tcx) |
| 368 | + } |
441 | 369 |
|
442 | | - #[inline(always)] |
443 | | - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { |
444 | | - LocalDefId::recover(tcx, dep_node).map($LocalName::new_unchecked) |
445 | | - } |
446 | | - } |
447 | | - }; |
| 370 | + #[inline(always)] |
| 371 | + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { |
| 372 | + LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked) |
| 373 | + } |
448 | 374 | } |
449 | | - |
450 | | -impl_for_typed_def_id! { ModDefId, LocalModDefId } |
0 commit comments