You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/mir/index.md
+62-1
Original file line number
Diff line number
Diff line change
@@ -255,7 +255,66 @@ but [you can read about those below](#promoted)).
255
255
256
256
## Representing constants
257
257
258
-
*to be written*
258
+
When code has reached the MIR stage, constants can generally come in two forms: *MIR constants* ([`mir::Constant`]) and *type system constants* ([`ty::Const`]).
259
+
MIR constants are used as operands: in `x + CONST`, `CONST` is a MIR constant; similarly, in `x + 2`, `2` is a MIR constant.
260
+
Type system constants are used in the type system, in particular for array lengths but also for const generics.
261
+
262
+
Generally, both kinds of constants can be "unevaluated" or "already evaluated".
263
+
And unevaluated constant simply stores the `DefId` of what needs to be evaluated to compute this result.
264
+
An evaluated constant (a "value") has already been computed; their representation differs between type system constants and MIR constants:
265
+
MIR constants evaluate to a `mir::ConstValue`; type system constants evaluate to a `ty::ValTree`.
266
+
267
+
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.
268
+
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.
269
+
270
+
### MIR constant values
271
+
272
+
In general, a MIR constant value (`mir::ConstValue`) was computed by evaluating some constant the user wrote.
273
+
This [const evaluation](../const-eval.md) produces a very low-level representation of the result in terms of individual bytes.
274
+
We call this an "indirect" constant (`mir::ConstValue::Indirect`) since the value is stored in-memory.
275
+
276
+
However, storing everything in-memory would be awfully inefficient. Hence there
277
+
are some other variants in `mir::ConstValue` that can represent certain simple
278
+
and common values more efficiently. In particular, everything that can be
279
+
directly written as a literal in Rust (integers, floats, chars, bools, but also
280
+
`"string literals"`and `b"byte string literals"`) has an optimized variant that
281
+
avoids the full overhead of the in-memory representation.
282
+
283
+
### ValTrees
284
+
285
+
An evaluated type system constant is a "valtree". The `ty::ValTree` datastructure
286
+
allows us to represent
287
+
288
+
* arrays,
289
+
* many structs,
290
+
* tuples,
291
+
* enums and,
292
+
* most primitives.
293
+
294
+
The most important rule for
295
+
this representation is that every value must be uniquely represented. In other
296
+
words: a specific value must only be representable in one specific way. For example: there is only
297
+
one way to represent an array of two integers as a `ValTree`:
0 commit comments