@@ -10,6 +10,7 @@ requires "./types.md"
1010requires "./value.md"
1111requires "./numbers.md"
1212requires "./decoding.md"
13+ requires "./pointer-int.md" // pointer/int encoding helpers live separately for readability
1314
1415module RT-DATA
1516 imports INT
@@ -27,6 +28,7 @@ module RT-DATA
2728 imports RT-NUMBERS
2829 imports RT-DECODING
2930 imports RT-TYPES
31+ imports RT-POINTER-INT // shared pointer/int encoding + decoding helpers
3032 imports KMIR-CONFIGURATION
3133
3234```
@@ -316,8 +318,6 @@ These helpers mark down, as we traverse the projection, what `Place` we are curr
316318 | CtxSubslice( List , Int , Int ) // start and end always counted from beginning
317319 | CtxPointerOffset( List, Int, Int ) // pointer offset for accessing elements with an offset (Offset, Origin Length)
318320
319- syntax ProjectionElem ::= PointerOffset( Int, Int ) // Same as subslice but coming from BinopOffset injected by us
320-
321321 syntax Contexts ::= List{Context, ""}
322322
323323 syntax Value ::= #buildUpdate ( Value , Contexts ) [function]
@@ -1456,28 +1456,6 @@ What can be supported without additional layout consideration is trivial casts b
14561456 requires lookupTy(TY_SOURCE) ==K lookupTy(TY_TARGET)
14571457```
14581458
1459- 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-
14811459Other ` Transmute ` casts that can be resolved are round-trip casts from type A to type B and then directly back from B to A.
14821460The first cast is reified as a ` thunk ` , the second one resolves it and eliminates the ` thunk ` :
14831461
@@ -1582,6 +1560,56 @@ Casting an integer to a `[u8; N]` array materialises its little-endian bytes.
15821560 rule #staticArrayLenBits(_OTHER) => 0 [owise]
15831561```
15841562
1563+ Transmuting a raw pointer to an integer (and back) uses the reversible encoding defined in ` RT-POINTER-INT ` .
1564+ Keeping these helpers in a dedicated module keeps this file focused on semantics while still reusing the canonical encoding.
1565+ The encoding serialises the pointer provenance, its place/projection, mutability and metadata into a natural number;
1566+ decoding rehydrates the pointer metadata and reinterprets the byte offset for the target pointee type.
1567+
1568+ ``` k
1569+ syntax Value ::= #ptrWithOffset ( Value , Int , TypeInfo ) [function, total]
1570+ rule #ptrWithOffset(PtrLocal(STACK, PLACE, MUT, metadata(SIZE, _, ORIGIN)), OFFSET, TYINFO)
1571+ => PtrLocal(STACK, PLACE, MUT, #convertMetadata(metadata(SIZE, OFFSET, ORIGIN), TYINFO))
1572+ rule #ptrWithOffset(VAL:Value, _, _) => VAL [owise]
1573+ ```
1574+
1575+ ``` k
1576+ rule <k> #cast(
1577+ PtrLocal(_, _, _, _) #as PTR,
1578+ castKindTransmute,
1579+ TY_SOURCE,
1580+ TY_TARGET
1581+ )
1582+ =>
1583+ #ptrIntValue(
1584+ #encodePtrInt(PTR, pointeeTy(lookupTy(TY_SOURCE))), // full Cantor encoding
1585+ #numTypeOf(lookupTy(TY_TARGET)) // signedness + width
1586+ )
1587+ ...
1588+ </k>
1589+ requires #isIntType(lookupTy(TY_TARGET))
1590+ andBool pointeeTy(lookupTy(TY_SOURCE)) =/=K TyUnknown
1591+
1592+ rule <k> #cast(
1593+ Integer(VAL, WIDTH, SIGNED) #as _INT,
1594+ castKindTransmute,
1595+ TY_SOURCE,
1596+ TY_TARGET
1597+ )
1598+ =>
1599+ #ptrWithOffset(
1600+ #decodePtrBase(#cantorUnpairLeft(#unsignedFromIntValue(VAL, WIDTH, SIGNED))),
1601+ #bytesToPtrOffset(
1602+ #cantorUnpairRight(#unsignedFromIntValue(VAL, WIDTH, SIGNED)),
1603+ pointeeTy(lookupTy(TY_TARGET))
1604+ ),
1605+ lookupTy(TY_TARGET)
1606+ )
1607+ ...
1608+ </k>
1609+ requires #isIntType(lookupTy(TY_SOURCE))
1610+ andBool pointeeTy(lookupTy(TY_TARGET)) =/=K TyUnknown
1611+ ```
1612+
15851613A transmutation from an integer to an enum is wellformed if:
15861614- The bit width of the incoming integer is the same as the discriminant type of the enum
15871615 (e.g. ` u8 -> i8 ` fine, ` u8 -> u16 ` not fine) - this is guaranteed by the compiler;
@@ -2197,7 +2225,7 @@ A trivial case where `binOpOffset` applies an offset of `0` is added with higher
21972225 _CHECKED)
21982226 =>
21992227 PtrLocal( STACK_DEPTH , PLACE , MUT, metadata(CURRENT_SIZE, CURRENT_OFFSET +Int OFFSET_VAL, staticSize(ORIGIN_SIZE)) )
2200- requires OFFSET_VAL >=Int 0
2228+ requires OFFSET_VAL >=Int 0
22012229 andBool CURRENT_OFFSET +Int OFFSET_VAL <=Int ORIGIN_SIZE
22022230 [preserves-definedness]
22032231```
0 commit comments