If you have read the few previous chapters, you now know that
many different intermediate representations to perform different kinds of analyses.
However, like in every data structure, you need a way to traverse the structure
and refer to other elements. In this chapter, you will find information on the
rustc uses for each intermediate representation.
NodeId is an identifier number that uniquely identifies an AST node within
a crate. Every node in the AST has its own
NodeId, including top-level items
such as structs, but also individual statements and expressions.
However, because they are absolute within a crate, adding or removing a single
node in the AST causes all the subsequent
NodeIds to change. This renders
NodeIds pretty much useless for incremental compilation, where you want as
few things as possible to change.
NodeIds are used in all the
rustc bits that operate directly on the AST,
like macro expansion and name resolution.
The HIR uses a bunch of different identifiers that coexist and serve different purposes.
DefId, as the name suggests, identifies a particular definition, or top-level item, in a given crate. It is composed of two parts: a
CrateNumwhich identifies the crate the definition comes from, and a
DefIndexwhich identifies the definition within the crate. Unlike
HirIds, there isn't a
DefIdfor every expression, which makes them more stable across compilations.
LocalDefIdis basically a
DefIdthat is known to come from the current crate. This allows us to drop the
CrateNumpart, and use the type system to ensure that only local definitions are passed to functions that expect a local definition.
HirIduniquely identifies a node in the HIR of the current crate. It is composed of two parts: an
local_idthat is unique within the
owner. This combination makes for more stable values which are helpful for incremental compilation. Unlike
HirIdcan refer to fine-grained entities like expressions, but stays local to the current crate.
BasicBlockidentifies a basic block. It points to an instance of
BasicBlockData, which can be retrieved by indexing into
Body::basic_blocks()(note that you must call a function; the field is private).
SourceScopeidentifies a name scope in the original source code. Used for diagnostics and for debuginfo in debuggers. It points to an instance of
SourceScopeData, which can be retrieved by indexing into
Promotedidentifies a promoted constant within another item (related to const evaluation). Note: it is unique only locally within the item, so it should be associated with a
GlobalIdwill give you a more specific identifier.