1
Fork 0

Remove dep_node comment duplication.

`rustc_middle` and `rustc_query_system` both have a file called
`dep_node.rs` with a big comment at the top, and the comments are very
similar. The one in `rustc_query_system` looks like the original, and
the one in `rustc_middle` is a copy with some improvements.

This commit removes the comment from `rustc_middle` and updates the one
in `rustc_query_system` to include the improvements. I did it this way
because `rustc_query_system` is the crate that defines `DepNode`, and so
seems like the right place for the comment.
This commit is contained in:
Nicholas Nethercote 2025-02-02 19:23:34 +11:00
parent 0825202cf2
commit 1fa9200475
2 changed files with 26 additions and 71 deletions

View file

@ -1,61 +1,3 @@
//! Nodes in the dependency graph.
//!
//! A node in the [dependency graph] is represented by a [`DepNode`].
//! A `DepNode` consists of a [`DepKind`] (which
//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
//! depends on the node's `DepKind`. Together, the kind and the fingerprint
//! fully identify a dependency node, even across multiple compilation sessions.
//! In other words, the value of the fingerprint does not depend on anything
//! that is specific to a given compilation session, like an unpredictable
//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
//! pointer. The concept behind this could be compared to how git commit hashes
//! uniquely identify a given commit. The fingerprinting approach has
//! a few advantages:
//!
//! * A `DepNode` can simply be serialized to disk and loaded in another session
//! without the need to do any "rebasing" (like we have to do for Spans and
//! NodeIds) or "retracing" (like we had to do for `DefId` in earlier
//! implementations of the dependency graph).
//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
//! memory without any post-processing (e.g., "abomination-style" pointer
//! reconstruction).
//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
//! refer to things that do not exist anymore. In previous implementations
//! `DepNode` contained a `DefId`. A `DepNode` referring to something that
//! had been removed between the previous and the current compilation session
//! could not be instantiated because the current compilation session
//! contained no `DefId` for thing that had been removed.
//!
//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
//! defines the `DepKind` enum. Each `DepKind` has its own parameters that are
//! needed at runtime in order to construct a valid `DepNode` fingerprint.
//! However, only `CompileCodegenUnit` and `CompileMonoItem` are constructed
//! explicitly (with `make_compile_codegen_unit` cq `make_compile_mono_item`).
//!
//! Because the macro sees what parameters a given `DepKind` requires, it can
//! "infer" some properties for each kind of `DepNode`:
//!
//! * Whether a `DepNode` of a given kind has any parameters at all. Some
//! `DepNode`s could represent global concepts with only one value.
//! * Whether it is possible, in principle, to reconstruct a query key from a
//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
//! in which case it is possible to map the node's fingerprint back to the
//! `DefId` it was computed from. In other cases, too much information gets
//! lost during fingerprint computation.
//!
//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
//! `DepNode::new()`, ensures that only valid `DepNode` instances can be
//! constructed. For example, the API does not allow for constructing
//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
//! More generally speaking, it relieves the user of the `DepNode` API of
//! having to know how to compute the expected fingerprint for a given set of
//! node parameters.
//!
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
use rustc_hir::definitions::DefPathHash; use rustc_hir::definitions::DefPathHash;

View file

@ -1,19 +1,20 @@
//! This module defines the `DepNode` type which the compiler uses to represent //! This module defines the [`DepNode`] type which the compiler uses to represent
//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which //! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc) //! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which //! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
//! depends on the node's `DepKind`. Together, the kind and the fingerprint //! depends on the node's `DepKind`. Together, the kind and the fingerprint
//! fully identify a dependency node, even across multiple compilation sessions. //! fully identify a dependency node, even across multiple compilation sessions.
//! In other words, the value of the fingerprint does not depend on anything //! In other words, the value of the fingerprint does not depend on anything
//! that is specific to a given compilation session, like an unpredictable //! that is specific to a given compilation session, like an unpredictable
//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a //! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
//! pointer. The concept behind this could be compared to how git commit hashes //! pointer. The concept behind this could be compared to how git commit hashes
//! uniquely identify a given commit and has a few advantages: //! uniquely identify a given commit. The fingerprinting approach has
//! a few advantages:
//! //!
//! * A `DepNode` can simply be serialized to disk and loaded in another session //! * A `DepNode` can simply be serialized to disk and loaded in another session
//! without the need to do any "rebasing (like we have to do for Spans and //! without the need to do any "rebasing" (like we have to do for Spans and
//! NodeIds) or "retracing" like we had to do for `DefId` in earlier //! NodeIds) or "retracing" (like we had to do for `DefId` in earlier
//! implementations of the dependency graph. //! implementations of the dependency graph).
//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc. //! implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
@ -26,10 +27,12 @@
//! could not be instantiated because the current compilation session //! could not be instantiated because the current compilation session
//! contained no `DefId` for thing that had been removed. //! contained no `DefId` for thing that had been removed.
//! //!
//! `DepNode` definition happens in `rustc_middle` with the `define_dep_nodes!()` macro. //! `DepNode` definition happens in `rustc_middle` with the
//! This macro defines the `DepKind` enum and a corresponding `DepConstructor` enum. The //! `define_dep_nodes!()` macro. This macro defines the `DepKind` enum. Each
//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at runtime in order //! `DepKind` has its own parameters that are needed at runtime in order to
//! to construct a valid `DepNode` fingerprint. //! construct a valid `DepNode` fingerprint. However, only `CompileCodegenUnit`
//! and `CompileMonoItem` are constructed explicitly (with
//! `make_compile_codegen_unit` and `make_compile_mono_item`).
//! //!
//! Because the macro sees what parameters a given `DepKind` requires, it can //! Because the macro sees what parameters a given `DepKind` requires, it can
//! "infer" some properties for each kind of `DepNode`: //! "infer" some properties for each kind of `DepNode`:
@ -41,6 +44,16 @@
//! in which case it is possible to map the node's fingerprint back to the //! in which case it is possible to map the node's fingerprint back to the
//! `DefId` it was computed from. In other cases, too much information gets //! `DefId` it was computed from. In other cases, too much information gets
//! lost during fingerprint computation. //! lost during fingerprint computation.
//!
//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
//! `DepNode::new()`, ensure that only valid `DepNode` instances can be
//! constructed. For example, the API does not allow for constructing
//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
//! More generally speaking, it relieves the user of the `DepNode` API of
//! having to know how to compute the expected fingerprint for a given set of
//! node parameters.
//!
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;