|
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