Skip to content

Commit 50030cc

Browse files
committed
feat(rt): Handle interior mutability during writeback
1 parent 596829b commit 50030cc

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
@@ -146,6 +148,21 @@ To make this function total, an optional `MaybeTy` is used.
146148
rule elemTy( _ ) => TyUnknown [owise]
147149
```
148150

151+
## Interior Mutability
152+
153+
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.
154+
155+
```k
156+
syntax Bool ::= #allowsInteriorMutation(TypeInfo) [function, total]
157+
// ------------------------------------------------------
158+
// Stable MIR serializes struct names as either `mirString` or a plain `String`.
159+
rule #allowsInteriorMutation(typeInfoStructType(mirString(NAME), _, _, _))
160+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
161+
rule #allowsInteriorMutation(typeInfoStructType(NAME:String, _, _, _))
162+
=> findString(NAME, "UnsafeCell", 0) =/=Int -1
163+
rule #allowsInteriorMutation(_) => false [owise]
164+
```
165+
149166
## Static and Dynamic Metadata for Types
150167

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