@@ -20,17 +20,44 @@ Additionally constant evaluation can be used to reduce the workload or binary
2020size at runtime by precomputing complex operations at compiletime and only
2121storing the result.
2222
23+ All uses of constant evaluation can either be categorized as "influencing the type system"
24+ (array lengths, enum variant discriminants, const generic parameters), or as solely being
25+ done to precompute expressions to be used at runtime.
26+
2327Constant evaluation can be done by calling the ` const_eval_* ` functions of ` TyCtxt ` .
2428They're the wrappers of the ` const_eval ` query.
2529
30+ ` static ` initializers must use the ` eval_static_initializer ` function. All other functions
31+ do not represent statics correctly and have thus assertions preventing their use on statics.
32+
2633The ` const_eval_* ` functions use a [ ` ParamEnv ` ] ( ./param_env.html ) of environment
2734in which the constant is evaluated (e.g. the function within which the constant is used)
2835and a [ ` GlobalId ` ] . The ` GlobalId ` is made up of an ` Instance ` referring to a constant
2936or static or of an ` Instance ` of a function and an index into the function's ` Promoted ` table.
3037
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 ` ] ).
38+ Constant evaluation returns a [ ` EvalToValTreeResult ` ] (for type system constants) or [ ` EvalToConstValueResult ` ] with either the error, or a
39+ representation of the constant.
40+
41+ Constants for the type system are encoded in "valtree representation". The ` ValTree ` datastructure
42+ allows us to represent arrays, many structs, tuples, enums and most primitives. The basic rule for
43+ being permitted in the type system is that every value must be uniquely represented. In other words:
44+ a specific value must only be representable in one specific way. For example: there is only one way
45+ to represent an array of two integers as a ` ValTree ` : ` ValTree::Branch(&[ValTree::Leaf(first_int), ValTree;:Leaf(second_int)]) ` .
46+ Even though theoretically a ` [u32; 2] ` could be encoded in a ` u64 ` and thus just be a ` ValTree::Leaf(bits_of_two_u32) ` , that
47+ is not a legal construction of ` ValTree ` (and is so complex to do, that it is unlikely to tempt anyone to do so).
48+ These rules also mean that some values are not representable. There can be no ` union ` s in type level
49+ constants, as it is not clear how they should be represented, because their active variant is unknown.
50+ Similarly there is no way to represent pointers, as addresses are unknown at compile-time and thus we
51+ cannot make any assumptions about them. References on the other hand can be represented, as equality
52+ for references is defined as equality on their value, so we ignore their address and just look at the
53+ backing value. This means that there is no difference in encoding for ` &42 ` and ` 42 ` .
54+ As a consequence, all decoding of ` ValTree ` must happen by matching on the type first and making decisions
55+ depending on that. The value itself gives no useful information without the type that belongs to it.
56+ One notable oddity is ` &str ` representation. There is no sized equivalent of it, so unlike slices we cannot
57+ choose to represent them as their sized variant (slices are represented as arrays). ` &str ` thus has
58+ its own ` ValTree ` variant ` Str ` . The advantage of using a custom variant is that we are able to translate
59+ parser/AST/HIR string literals without any conversion as we use the same (` Symbol ` ) representation.
60+
3461Other constants get represented as [ ` ConstValue::Scalar ` ]
3562or [ ` ConstValue::Slice ` ] if possible. This means that the ` const_eval_* `
3663functions cannot be used to create miri-pointers to the evaluated constant.
@@ -42,4 +69,5 @@ If you need the value of a constant inside Miri, you need to directly work with
4269[ `ConstValue::Slice` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.Slice
4370[ `ConstValue::ByRef` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.ByRef
4471[ `EvalToConstValueResult` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToConstValueResult.html
72+ [ `EvalToValTreeResult` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToValTreeResult.html
4573[ `eval_const_to_op` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir/interpret/struct.InterpCx.html#method.eval_const_to_op
0 commit comments