You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Transmuting a pointer to an integer discards provenance and reinterprets the pointer’s offset as a value of the target integer type.
1460
-
1461
-
```k
1462
-
// `prove-rs/interior-mut3.rs` needs this
1463
-
// TODO: check its correctness, I assume the pointer offset is the address here and we can use it to recover the PtrLocal
1464
-
rule <k> #cast(
1465
-
PtrLocal(_, _, _, metadata(_, PTR_OFFSET, _)),
1466
-
castKindTransmute,
1467
-
_TY_SOURCE,
1468
-
TY_TARGET
1469
-
)
1470
-
=>
1471
-
#intAsType(
1472
-
PTR_OFFSET,
1473
-
#bitWidth(#numTypeOf(lookupTy(TY_TARGET))),
1474
-
#numTypeOf(lookupTy(TY_TARGET))
1475
-
)
1476
-
...
1477
-
</k>
1478
-
requires #isIntType(lookupTy(TY_TARGET))
1479
-
```
1480
-
1481
1460
Other `Transmute` casts that can be resolved are round-trip casts from type A to type B and then directly back from B to A.
1482
1461
The first cast is reified as a `thunk`, the second one resolves it and eliminates the `thunk`:
1483
1462
@@ -1582,17 +1561,57 @@ Casting an integer to a `[u8; N]` array materialises its little-endian bytes.
1582
1561
rule #staticArrayLenBits(_OTHER) => 0 [owise]
1583
1562
```
1584
1563
1585
-
A transmutation from an integer to an enum is wellformed if:
1586
-
- The bit width of the incoming integer is the same as the discriminant type of the enum
1587
-
(e.g. `u8 -> i8` fine, `u8 -> u16` not fine) - this is guaranteed by the compiler;
1588
-
- The incoming integer has a bit pattern that matches a discriminant of the enum
1589
-
(e.g. `255_u8` and `-1_i8` fine iff `0b1111_1111` is a discriminant of the enum);
1590
-
1591
-
Note that discriminants are stored as `u128` in the type data even if they are signed
1592
-
or unsigned at the source level. This means that our approach to soundly transmute an
1593
-
integer into a enum is to treat the incoming integer as unsigned (converting if signed),
1594
-
and check if the value is in the discriminants. If yes, find the corresponding variant
1595
-
index; if not, return `#UBErrorInvalidDiscriminantsInEnumCast`.
1564
+
Transmuting a pointer to an integer uses the helpers defined in `RT-POINTER-INT` to encode the entire pointer (stack depth, place, mutability, and metadata) into a single natural number; decoding applies the inverse helpers. The encoding must fit into the target integer bit-width, otherwise the transmute is stuck.
1565
+
1566
+
```k
1567
+
syntax Value ::= #ptrWithOffset ( Value , Int , TypeInfo ) [function, total]
Another specialisation is getting the discriminant of `enum`s without fields after converting some integer data to it
1613
+
(see `#discriminant` and `rvalueDiscriminant`).
1614
+
If none of the `enum` variants has any fields, the `Transmute` of a number to the `enum` data is necessarily just the discriminant itself., and can be returned as the integer value afgter adjusting to the byte length of the discriminant:
0 commit comments