Skip to content

Commit 349e03b

Browse files
committed
feat(rt): Handle interior mutability during writeback
1 parent 66aec6d commit 349e03b

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
@@ -248,6 +248,19 @@ A `Deref` projection in the projections list changes the target of the write ope
248248
rule <k> #traverseProjection(_, VAL, .ProjectionElems, _) ~> #readProjection(false) => VAL ... </k>
249249
rule <k> #traverseProjection(_, VAL, .ProjectionElems, _) ~> (#readProjection(true) => #writeMoved ~> VAL) ... </k>
250250
251+
// interior mutability permits projected writeback
252+
rule <k> #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS)
253+
~> #writeProjection(NEW)
254+
=> #forceSetLocal(local(I), #buildUpdate(NEW, CONTEXTS))
255+
...
256+
</k>
257+
<locals> LOCALS </locals>
258+
requires CONTEXTS =/=K .Contexts
259+
andBool 0 <=Int I andBool I <Int size(LOCALS)
260+
andBool isTypedLocal(LOCALS[I])
261+
andBool #allowsInteriorMutation(lookupTy(tyOfLocal({LOCALS[I]}:>TypedLocal)))
262+
[priority(40), preserves-definedness]
263+
251264
rule <k> #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS)
252265
~> #writeProjection(NEW)
253266
=> #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
@@ -101,6 +103,21 @@ To make this function total, an optional `MaybeTy` is used.
101103
rule elemTy( _ ) => TyUnknown [owise]
102104
```
103105

106+
## Interior Mutability
107+
108+
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.
109+
110+
```k
111+
syntax Bool ::= #allowsInteriorMutation(TypeInfo) [function, total]
112+
// ------------------------------------------------------
113+
// Stable MIR serializes struct names as either `mirString` or a plain `String`.
114+
rule #allowsInteriorMutation(typeInfoStructType(mirString(NAME), _, _, _))
115+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
116+
rule #allowsInteriorMutation(typeInfoStructType(NAME:String, _, _, _))
117+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
118+
rule #allowsInteriorMutation(_) => false [owise]
119+
```
120+
104121
## Static and Dynamic Metadata for Types
105122

106123
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)