diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/data.md b/kmir/src/kmir/kdist/mir-semantics/rt/data.md index 9fd89c6a9..d56cbf77f 100644 --- a/kmir/src/kmir/kdist/mir-semantics/rt/data.md +++ b/kmir/src/kmir/kdist/mir-semantics/rt/data.md @@ -248,6 +248,19 @@ A `Deref` projection in the projections list changes the target of the write ope rule #traverseProjection(_, VAL, .ProjectionElems, _) ~> #readProjection(false) => VAL ... rule #traverseProjection(_, VAL, .ProjectionElems, _) ~> (#readProjection(true) => #writeMoved ~> VAL) ... + // interior mutability permits projected writeback + rule #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS) + ~> #writeProjection(NEW) + => #forceSetLocal(local(I), #buildUpdate(NEW, CONTEXTS)) + ... + + LOCALS + requires CONTEXTS =/=K .Contexts + andBool 0 <=Int I andBool I TypedLocal))) + [priority(40), preserves-definedness] + rule #traverseProjection(toLocal(I), _ORIGINAL, .ProjectionElems, CONTEXTS) ~> #writeProjection(NEW) => #setLocalValue(place(local(I), .ProjectionElems), #buildUpdate(NEW, CONTEXTS)) diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/types.md b/kmir/src/kmir/kdist/mir-semantics/rt/types.md index ee42a817c..967dda983 100644 --- a/kmir/src/kmir/kdist/mir-semantics/rt/types.md +++ b/kmir/src/kmir/kdist/mir-semantics/rt/types.md @@ -8,6 +8,8 @@ requires "value.md" module RT-TYPES imports BOOL + imports INT + imports STRING imports MAP imports K-EQUAL @@ -146,6 +148,21 @@ To make this function total, an optional `MaybeTy` is used. rule elemTy( _ ) => TyUnknown [owise] ``` +## Interior Mutability + +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. + +```k + syntax Bool ::= #allowsInteriorMutation(TypeInfo) [function, total] + // ------------------------------------------------------ + // Stable MIR serializes struct names as either `mirString` or a plain `String`. + rule #allowsInteriorMutation(typeInfoStructType(mirString(NAME), _, _, _)) + => findString(NAME, "UnsafeCell", 0) =/=Int -1 + rule #allowsInteriorMutation(typeInfoStructType(NAME:String, _, _, _)) + => findString(NAME, "UnsafeCell", 0) =/=Int -1 + rule #allowsInteriorMutation(_) => false [owise] +``` + ## Static and Dynamic Metadata for Types References to data on the heap or stack may require metadata, most commonly the size of slices, which is not statically known.