Skip to content

Add a section on identifiers in the MIR #951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 7, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions src/identifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A [`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 in a crate, adding or removing a single
However, because they are absolute within a crate, adding or removing a single
node in the AST causes all the subsequent [`NodeId`]s to change. This renders
[`NodeId`]s pretty much useless for incremental compilation, where you want as
few things as possible to change.
Expand All @@ -31,14 +31,17 @@ The HIR uses a bunch of different identifiers that coexist and serve different p
the crate the definition comes from, and a [`DefIndex`] which identifies the definition
within the crate. Unlike [`NodeId`]s, there isn't a [`DefId`] for every expression, which
makes them more stable across compilations.

- A [`LocalDefId`] is basically a [`DefId`] that is known to come from the current crate.
This allows us to drop the [`CrateNum`] part, and use the type system to ensure that
only local definitions are passed to functions that expect a local definition.

- A [`HirId`] uniquely identifies a node in the HIR of the current crate. It is composed
of two parts: an `owner` and a `local_id` that is unique within the `owner`. This
combination makes for more stable values which are helpful for incremental compilation.
Unlike [`DefId`]s, a [`HirId`] can refer to [fine-grained entities][Node] like expressions,
but stays local to the current crate.

- A [`BodyId`] identifies a HIR [`Body`] in the current crate. It is currenty only
a wrapper around a [`HirId`]. For more info about HIR bodies, please refer to the
[HIR chapter][hir-bodies].
Expand All @@ -60,4 +63,46 @@ See the [HIR chapter][hir-map] for more detailed information.

## In the MIR

**TODO**
- [`BasicBlock`] identifies 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).

- [`Local`] identifies a local variable in a function. Its associated data is in
[`LocalDecl`], which can be retrieved by indexing into [`Body.local_decls`].

- [`Field`] identifies a struct's, union's, or enum variant's field. It is used
as a "projection" in [`Place`].

- [`SourceScope`] identifies 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
[`Body.source_scopes`].

- [`Promoted`] identifies 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 `DefId`.
[`GlobalId`] will give you a more specific identifier (TODO).

- [`GlobalId`] identifies a global variable: a `const`, a `static`, a `const fn`
where all arguments are [zero-sized types], or a promoted constant.

- [`Location`] represents the location in the MIR of a statement or terminator.
It identifies the block (using [`BasicBlock`]) and the index of the statement
or terminator in the block.

[`BasicBlock`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlock.html
[`BasicBlockData`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BasicBlockData.html
[`Body::basic_blocks()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#method.basic_blocks
[`Local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Local.html
[`LocalDecl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.LocalDecl.html
[`Body.local_decls`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.local_decls
[`Field`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Field.html
[`Place`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Place.html
[`SourceScope`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.SourceScope.html
[`SourceScopeData`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.SourceScopeData.html
[`Body.source_scopes`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.source_scopes
[`Promoted`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Promoted.html
[`GlobalId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.GlobalId.html
[`Location`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Location.html
[zero-sized types]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts