]>
Commit | Line | Data |
---|---|---|
a1dfa0c6 XL |
1 | # Constant Evaluation |
2 | ||
3 | Constant evaluation is the process of computing values at compile time. For a | |
4 | specific item (constant/static/array length) this happens after the MIR for the | |
5 | item is borrow-checked and optimized. In many cases trying to const evaluate an | |
6 | item will trigger the computation of its MIR for the first time. | |
7 | ||
6a06907d | 8 | Prominent examples are: |
a1dfa0c6 XL |
9 | |
10 | * The initializer of a `static` | |
11 | * Array length | |
12 | * needs to be known to reserve stack or heap space | |
13 | * Enum variant discriminants | |
14 | * needs to be known to prevent two variants from having the same | |
15 | discriminant | |
16 | * Patterns | |
17 | * need to be known to check for overlapping patterns | |
18 | ||
19 | Additionally constant evaluation can be used to reduce the workload or binary | |
20 | size at runtime by precomputing complex operations at compiletime and only | |
21 | storing the result. | |
22 | ||
6a06907d XL |
23 | Constant evaluation can be done by calling the `const_eval_*` functions of `TyCtxt`. |
24 | They're the wrappers of the `const_eval` query. | |
25 | ||
26 | The `const_eval_*` functions use a [`ParamEnv`](./param_env.html) of environment | |
27 | in which the constant is evaluated (e.g. the function within which the constant is used) | |
28 | and a [`GlobalId`]. The `GlobalId` is made up of an `Instance` referring to a constant | |
29 | or static or of an `Instance` of a function and an index into the function's `Promoted` table. | |
30 | ||
31 | Constant evaluation returns a [`EvalToConstValueResult`] with either the error, or a | |
32 | representation of the constant. `static` initializers are always represented as | |
33 | [`miri`](./miri.html) virtual memory allocations (via [`ConstValue::ByRef`]). | |
34 | Other constants get represented as [`ConstValue::Scalar`] | |
35 | or [`ConstValue::Slice`] if possible. This means that the `const_eval_*` | |
36 | functions cannot be used to create miri-pointers to the evaluated constant. | |
37 | If you need the value of a constant inside Miri, you need to directly work with | |
38 | [`eval_const_to_op`]. | |
39 | ||
40 | [`GlobalId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.GlobalId.html | |
41 | [`ConstValue::Scalar`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.Scalar | |
42 | [`ConstValue::Slice`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.Slice | |
43 | [`ConstValue::ByRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.ByRef | |
44 | [`EvalToConstValueResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToConstValueResult.html | |
45 | [`eval_const_to_op`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/interpret/struct.InterpCx.html#method.eval_const_to_op |