]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-dev-guide/src/const-eval.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / src / const-eval.md
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
8 Prominent examples are:
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
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