Home Explore Blog CI



rustc

4th chunk of `src/mir/index.md`
302941eee47ce7d3a3c36209d250a110ba9c3e90bf303a5200000001000008f1
  - **Projections**, which are fields or other things that "project
    out" from a base place. These are represented by the [newtype'd] type
    [`ProjectionElem`]. So e.g. the place `_1.f` is a projection,
    with `f` being the "projection element" and `_1` being the base
    path. `*_1` is also a projection, with the `*` being represented
    by the [`ProjectionElem::Deref`] element.
- **Rvalues** are represented by the enum [`Rvalue`].
- **Operands** are represented by the enum [`Operand`].

## Representing constants

When code has reached the MIR stage, constants can generally come in two forms:
*MIR constants* ([`mir::Constant`]) and *type system constants* ([`ty::Const`]).
MIR constants are used as operands: in `x + CONST`, `CONST` is a MIR constant;
similarly, in `x + 2`, `2` is a MIR constant. Type system constants are used in
the type system, in particular for array lengths but also for const generics.

Generally, both kinds of constants can be "unevaluated" or "already evaluated".
An unevaluated constant simply stores the `DefId` of what needs to be evaluated
to compute this result. An evaluated constant (a "value") has already been
computed; their representation differs between type system constants and MIR
constants: MIR constants evaluate to a `mir::ConstValue`; type system constants
evaluate to a `ty::ValTree`.

Type system constants have some more variants to support const generics: they
can refer to local const generic parameters, and they are subject to inference.
Furthermore, the `mir::Constant::Ty` variant lets us use an arbitrary type
system constant as a MIR constant; this happens whenever a const generic
parameter is used as an operand.

### MIR constant values

In general, a MIR constant value (`mir::ConstValue`) was computed by evaluating
some constant the user wrote. This [const evaluation](../const-eval.md) produces
a very low-level representation of the result in terms of individual bytes. We
call this an "indirect" constant (`mir::ConstValue::Indirect`) since the value
is stored in-memory.

However, storing everything in-memory would be awfully inefficient. Hence there
are some other variants in `mir::ConstValue` that can represent certain simple
and common values more efficiently. In particular, everything that can be

Title: Constants in MIR: Representation and Types
Summary
Projections in MIR represent fields or dereferences, with `ProjectionElem` handling these. Rvalues and Operands are enums representing the respective concepts. Constants in MIR are `mir::Constant` (MIR constants) or `ty::Const` (type system constants). Both can be unevaluated (storing the `DefId`) or evaluated. Evaluated MIR constants become `mir::ConstValue`, while type system constants become `ty::ValTree`. Type system constants support const generics and inference. `mir::Constant::Ty` allows using type system constants as MIR constants. MIR constant values (`mir::ConstValue`) result from const evaluation and can be stored as an "indirect" constant (`mir::ConstValue::Indirect`).