Skip to content

Commit bbee7f9

Browse files
Stevengreclaude
andcommitted
feat(rt): support transmuting pointer to integer type
Add a `#cast` rule for `castKindTransmute` that handles `PtrLocal` to integer type conversion. The rule extracts the pointer offset from metadata and converts it to the target integer type via `#intAsType`. A helper function `#ptrOffsetBytes` computes byte offsets from pointer offsets, accounting for array element sizes when the pointee is an unsized array type. This fixes the `interior-mut3` test which uses `UnsafeCell::get()` (internally transmutes a pointer to `usize` for alignment checks). The proof now passes cleanly in 333 steps instead of getting stuck on unresolved alignment assertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b694d02 commit bbee7f9

5 files changed

Lines changed: 57 additions & 64 deletions

File tree

kmir/src/kmir/kdist/mir-semantics/rt/data.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,45 @@ What can be supported without additional layout consideration is trivial casts b
16241624
requires lookupTy(TY_SOURCE) ==K lookupTy(TY_TARGET)
16251625
```
16261626

1627+
Transmuting a pointer to an integer discards provenance and reinterprets the pointer's offset as a value of the target integer type.
1628+
1629+
```k
1630+
syntax Int ::= #ptrOffsetBytes ( Int , MaybeTy ) [function, total]
1631+
rule #ptrOffsetBytes(PTR_OFFSET, _TY:Ty) => 0
1632+
requires PTR_OFFSET ==Int 0
1633+
rule #ptrOffsetBytes(PTR_OFFSET, TY:Ty)
1634+
=> PTR_OFFSET *Int #elemSize(#lookupMaybeTy(elemTy(lookupTy(TY))))
1635+
requires PTR_OFFSET =/=Int 0
1636+
andBool #isUnsizedArrayType(lookupTy(TY))
1637+
rule #ptrOffsetBytes(_, _) => -1 [owise] // should not happen
1638+
1639+
syntax Bool ::= #isUnsizedArrayType ( TypeInfo ) [function, total]
1640+
rule #isUnsizedArrayType(typeInfoArrayType(_, noTyConst)) => true
1641+
rule #isUnsizedArrayType(_) => false [owise]
1642+
```
1643+
1644+
```k
1645+
rule <k> #cast(
1646+
PtrLocal(_, _, _, metadata(_, PTR_OFFSET, _)),
1647+
castKindTransmute,
1648+
TY_SOURCE,
1649+
TY_TARGET
1650+
)
1651+
=>
1652+
#intAsType(
1653+
#ptrOffsetBytes(
1654+
PTR_OFFSET,
1655+
pointeeTy(#lookupMaybeTy(TY_SOURCE))
1656+
),
1657+
#bitWidth(#numTypeOf(lookupTy(TY_TARGET))),
1658+
#numTypeOf(lookupTy(TY_TARGET))
1659+
)
1660+
...
1661+
</k>
1662+
requires #isIntType(lookupTy(TY_TARGET))
1663+
andBool 0 <=Int #ptrOffsetBytes(PTR_OFFSET,pointeeTy(#lookupMaybeTy(TY_SOURCE)))
1664+
```
1665+
16271666
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.
16281667
The first cast is reified as a `thunk`, the second one resolves it and eliminates the `thunk`:
16291668

kmir/src/tests/integration/data/prove-rs/interior-mut3-fail.rs renamed to kmir/src/tests/integration/data/prove-rs/interior-mut3.rs

File renamed without changes.

kmir/src/tests/integration/data/prove-rs/show/interior-mut3-fail.main.expected

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
┌─ 1 (root, init)
3+
│ #execTerminator ( terminator ( ... kind: terminatorKindCall ( ... func: operandC
4+
│ span: 0
5+
6+
│ (333 steps)
7+
├─ 3 (terminal)
8+
│ #EndProgram ~> .K
9+
│ function: main
10+
11+
┊ constraint: true
12+
┊ subst: ...
13+
└─ 2 (leaf, target, terminal)
14+
#EndProgram ~> .K
15+
16+
17+

kmir/src/tests/integration/test_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
PROVE_SHOW_SPECS = [
4545
'local-raw-fail',
4646
'interior-mut-fail',
47-
'interior-mut3-fail',
47+
'interior-mut3',
4848
'iter_next_3',
4949
'assert_eq_exp',
5050
'bitwise-not-shift',

0 commit comments

Comments
 (0)