This takes the `AllocId` out of PrimValKind, replacing it with a
`relocation` field on `PrimVal`, which is closer to an earlier design
for `PrimVal` I discussed with @eddyb.
This commit prepares the code for removing the `PrimValKind` from
`PrimVal` and making them more pure bitbags. The only code dealing with
`PrimValKind` will be code making decisions like "what kind of operation
do I need to do on these bits", like operators and casting. Transmutes
of `PrimVal`s will become true no-ops, not even adjusting a `kind`
field.
This commit also removes my horrible `value_to_primval` hack that made
an allocation for every `ByVal` passed in, so it could use `read_value`
to get a `PrimVal` with the right kind. Now I just compute the
`PrimValKind` from the `Ty` and re-tag the `PrimVal`.
The code got slightly messier in some areas here, but I think a _lot_ of
code will simplify in obvious ways once I remove the `kind` field from
`PrimVal`.
Gosh, if my commit messages aren't turning into essays these days.
Now instead of holding a native type based on the tag, all PrimVals
store a u64 (the `bits`), along with a `kind` corresponding to the
variant as it would be in the old PrimVal representation.
This commit makes no major optimizations and attempts to not change any
behaviour. There will be commits to follow that make use of this
representation to eliminate unnecessary allocation hacks like in
`value_to_primval`.
A number of places could be even more cleaned up after this commit,
particularly in `cast.rs`.
Previously, you could perform the following, if you assume we could make
`Cell<i32>` into a primitive. (Alternately, you could achieve this with
unsafe code):
x = Cell::new(12);
y = &x;
// Miri locals array:
// x = ByRef(alloc123);
// y = ByVal(Ptr(alloc123));
//
// Miri allocations:
// alloc123: [12, 0, 0, 0]
x.set(42);
// Miri locals array:
// x = ByVal(I32(42));
// y = ByVal(Ptr(alloc123));
//
// Miri allocations:
// alloc123: [12, 0, 0, 0]
Notice how `y` still refers to the allocation that used to represent
`x`. But now `x` was changed to `42` and `y` is still looking at memory
containing `12`.
Now, instead, we keep `x` as a `ByRef` and write the `42` constant into
it.
Unit test to follow in the next commit.