|
8 | 8 | // option. This file may not be copied, modified, or distributed
|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
| 11 | + |
| 12 | +//! This module defines the `DepNode` type which the compiler uses to represent |
| 13 | +//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which |
| 14 | +//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc) |
| 15 | +//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which |
| 16 | +//! depends on the node's `DepKind`. Together, the kind and the fingerprint |
| 17 | +//! fully identify a dependency node, even across multiple compilation sessions. |
| 18 | +//! In other words, the value of the fingerprint does not depend on anything |
| 19 | +//! that is specific to a given compilation session, like an unpredictable |
| 20 | +//! interning key (e.g. NodeId, DefId, Symbol) or the numeric value of a |
| 21 | +//! pointer. The concept behind this could be compared to how git commit hashes |
| 22 | +//! uniquely identify a given commit and has a few advantages: |
| 23 | +//! |
| 24 | +//! * A `DepNode` can simply be serialized to disk and loaded in another session |
| 25 | +//! without the need to do any "rebasing (like we have to do for Spans and |
| 26 | +//! NodeIds) or "retracing" like we had to do for `DefId` in earlier |
| 27 | +//! implementations of the dependency graph. |
| 28 | +//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to |
| 29 | +//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc. |
| 30 | +//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into |
| 31 | +//! memory without any post-processing (e.g. "abomination-style" pointer |
| 32 | +//! reconstruction). |
| 33 | +//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that |
| 34 | +//! refer to things that do not exist anymore. In previous implementations |
| 35 | +//! `DepNode` contained a `DefId`. A `DepNode` referring to something that |
| 36 | +//! had been removed between the previous and the current compilation session |
| 37 | +//! could not be instantiated because the current compilation session |
| 38 | +//! contained no `DefId` for thing that had been removed. |
| 39 | +//! |
| 40 | +//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro |
| 41 | +//! defines the `DepKind` enum and a corresponding `DepConstructor` enum. The |
| 42 | +//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at |
| 43 | +//! runtime in order to construct a valid `DepNode` fingerprint. |
| 44 | +//! |
| 45 | +//! Because the macro sees what parameters a given `DepKind` requires, it can |
| 46 | +//! "infer" some properties for each kind of `DepNode`: |
| 47 | +//! |
| 48 | +//! * Whether a `DepNode` of a given kind has any parameters at all. Some |
| 49 | +//! `DepNode`s, like `Krate`, represent global concepts with only one value. |
| 50 | +//! * Whether it is possible, in principle, to reconstruct a query key from a |
| 51 | +//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter, |
| 52 | +//! in which case it is possible to map the node's fingerprint back to the |
| 53 | +//! `DefId` it was computed from. In other cases, too much information gets |
| 54 | +//! lost during fingerprint computation. |
| 55 | +//! |
| 56 | +//! The `DepConstructor` enum, together with `DepNode::new()` ensures that only |
| 57 | +//! valid `DepNode` instances can be constructed. For example, the API does not |
| 58 | +//! allow for constructing parameterless `DepNode`s with anything other |
| 59 | +//! than a zeroed out fingerprint. More generally speaking, it relieves the |
| 60 | +//! user of the `DepNode` API of having to know how to compute the expected |
| 61 | +//! fingerprint for a given set of node parameters. |
| 62 | +
|
11 | 63 | use hir::def_id::{CrateNum, DefId};
|
12 | 64 | use hir::map::DefPathHash;
|
13 | 65 |
|
|
0 commit comments