Skip to content

Commit

Permalink
Fix line lengths
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Mar 31, 2021
1 parent 48ca0bf commit 3ba5e47
Showing 1 changed file with 23 additions and 19 deletions.
42 changes: 23 additions & 19 deletions src/const-eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,34 @@ in which the constant is evaluated (e.g. the function within which the constant
and a [`GlobalId`]. The `GlobalId` is made up of an `Instance` referring to a constant
or static or of an `Instance` of a function and an index into the function's `Promoted` table.

Constant evaluation returns a [`EvalToValTreeResult`] (for type system constants) or [`EvalToConstValueResult`] with either the error, or a
representation of the constant.
Constant evaluation returns a [`EvalToValTreeResult`] (for type system constants) or
[`EvalToConstValueResult`] with either the error, or a representation of the constant.

Constants for the type system are encoded in "valtree representation". The `ValTree` datastructure
allows us to represent arrays, many structs, tuples, enums and most primitives. The basic rule for
being permitted in the type system is that every value must be uniquely represented. In other words:
a specific value must only be representable in one specific way. For example: there is only one way
to represent an array of two integers as a `ValTree`: `ValTree::Branch(&[ValTree::Leaf(first_int), ValTree;:Leaf(second_int)])`.
Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a `ValTree::Leaf(bits_of_two_u32)`, that
is not a legal construction of `ValTree` (and is so complex to do, so it is unlikely anyone is tempted to do so).
being permitted in the type system is that every value must be uniquely represented. In other
words: a specific value must only be representable in one specific way. For example: there is only
one way to represent an array of two integers as a `ValTree`:
`ValTree::Branch(&[ValTree::Leaf(first_int), ValTree;:Leaf(second_int)])`.
Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a
`ValTree::Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree`
(and is so complex to do, so it is unlikely anyone is tempted to do so).

These rules also mean that some values are not representable. There can be no `union`s in type level
constants, as it is not clear how they should be represented, because their active variant is unknown.
Similarly there is no way to represent pointers, as addresses are unknown at compile-time and thus we
cannot make any assumptions about them. References on the other hand can be represented, as equality
for references is defined as equality on their value, so we ignore their address and just look at the
backing value. This means that there is no difference in encoding for `&42` and `42`.
These rules also mean that some values are not representable. There can be no `union`s in type
level constants, as it is not clear how they should be represented, because their active variant
is unknown. Similarly there is no way to represent pointers, as addresses are unknown at
compile-time and thus we cannot make any assumptions about them. References on the other hand
can be represented, as equality for references is defined as equality on their value, so we
ignore their address and just look at the backing value.
This means that there is no difference in encoding for `&42` and `42`.

As a consequence, all decoding of `ValTree` must happen by matching on the type first and making decisions
depending on that. The value itself gives no useful information without the type that belongs to it.
One notable oddity is `&str` representation. There is no sized equivalent of it, so unlike slices we cannot
choose to represent them as their sized variant (slices are represented as arrays). `&str` thus has
its own `ValTree` variant `Str`. The advantage of using a custom variant is that we are able to translate
parser/AST/HIR string literals without any conversion as we use the same (`Symbol`) representation.
As a consequence, all decoding of `ValTree` must happen by matching on the type first and making
decisions depending on that. The value itself gives no useful information without the type that
belongs to it. One notable oddity is `&str` representation. There is no sized equivalent of it,
so unlike slices we cannot choose to represent them as their sized variant (slices are represented
as arrays). `&str` thus has its own `ValTree` variant `Str`. The advantage of using a custom
variant is that we are able to translate parser/AST/HIR string literals without any conversion
as we use the same (`Symbol`) representation.

Other constants get represented as [`ConstValue::Scalar`]
or [`ConstValue::Slice`] if possible. This means that the `const_eval_*`
Expand Down

0 comments on commit 3ba5e47

Please sign in to comment.