Skip to content

Commit 84f3179

Browse files
committed
feat(rt): Handle interior mutability during writeback
1 parent f45bd7b commit 84f3179

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,19 @@ A `Deref` projection in the projections list changes the target of the write ope
255255
rule <k> #traverseProjection(_, VAL, .ProjectionElems, _) ~> #readProjection(false) => VAL ... </k>
256256
rule <k> #traverseProjection(_, VAL, .ProjectionElems, _) ~> (#readProjection(true) => #writeMoved ~> VAL) ... </k>
257257
258+
// interior mutability permits projected writeback
259+
rule <k> #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS)
260+
~> #writeProjection(NEW)
261+
=> #forceSetLocal(local(I), #buildUpdate(NEW, CONTEXTS))
262+
...
263+
</k>
264+
<locals> LOCALS </locals>
265+
requires CONTEXTS =/=K .Contexts
266+
andBool 0 <=Int I andBool I <Int size(LOCALS)
267+
andBool isTypedLocal(LOCALS[I])
268+
andBool #allowsInteriorMutation(lookupTy(tyOfLocal({LOCALS[I]}:>TypedLocal)))
269+
[priority(40), preserves-definedness]
270+
258271
rule <k> #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS)
259272
~> #writeProjection(NEW)
260273
=> #setLocalValue(place(local(I), .ProjectionElems), #buildUpdate(NEW, CONTEXTS))

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ requires "value.md"
88
99
module RT-TYPES
1010
imports BOOL
11+
imports INT
12+
imports STRING
1113
imports MAP
1214
imports K-EQUAL
1315
@@ -145,6 +147,21 @@ To make this function total, an optional `MaybeTy` is used.
145147
rule elemTy( _ ) => TyUnknown [owise]
146148
```
147149

150+
## Interior Mutability
151+
152+
Rust models interior mutability with `UnsafeCell`. When the runtime determines whether a projected write can observe mutation through a shared reference, it relies on `#allowsInteriorMutation` to detect that marker inside Stable MIR type metadata.
153+
154+
```k
155+
syntax Bool ::= #allowsInteriorMutation(TypeInfo) [function, total]
156+
// ------------------------------------------------------
157+
// Stable MIR serializes struct names as either `mirString` or a plain `String`.
158+
rule #allowsInteriorMutation(typeInfoStructType(mirString(NAME), _, _, _))
159+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
160+
rule #allowsInteriorMutation(typeInfoStructType(NAME:String, _, _, _))
161+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
162+
rule #allowsInteriorMutation(_) => false [owise]
163+
```
164+
148165
## Static and Dynamic Metadata for Types
149166

150167
References to data on the heap or stack may require metadata, most commonly the size of slices, which is not statically known.

0 commit comments

Comments
 (0)