Skip to content

Commit 389add9

Browse files
committed
fix(rt): Handle zero-sized locals on borrow
1 parent fc12dcc commit 389add9

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,18 @@ This eliminates any `Deref` projections from the place, and also resolves `Index
10871087
// rule #projectionsFor(CtxPointerOffset(OFFSET, ORIGIN_LENGTH) CTXS, PROJS) => #projectionsFor(CTXS, projectionElemSubslice(OFFSET, ORIGIN_LENGTH, false) PROJS)
10881088
rule #projectionsFor(CtxPointerOffset( _, OFFSET, ORIGIN_LENGTH) CTXS, PROJS) => #projectionsFor(CTXS, PointerOffset(OFFSET, ORIGIN_LENGTH) PROJS)
10891089
1090+
// Borrowing a zero-sized local that is still `NewLocal`: initialise it, then reuse the regular rule.
1091+
rule <k> rvalueRef(REGION, KIND, place(local(I), PROJS))
1092+
=> #forceSetLocal(local(I), Aggregate(variantIdx(0), .List))
1093+
~> rvalueRef(REGION, KIND, place(local(I), PROJS))
1094+
...
1095+
</k>
1096+
<locals> LOCALS </locals>
1097+
requires 0 <=Int I andBool I <Int size(LOCALS)
1098+
andBool isNewLocal(LOCALS[I])
1099+
andBool #zeroSizedType(lookupTy(tyOfLocal(getLocal(LOCALS, I))))
1100+
[preserves-definedness] // valid list indexing checked, zero-sized locals materialise trivially
1101+
10901102
rule <k> rvalueRef(_REGION, KIND, place(local(I), PROJS))
10911103
=> #traverseProjection(toLocal(I), getValue(LOCALS, I), PROJS, .Contexts)
10921104
~> #forRef(#mutabilityOf(KIND), metadata(#metadataSize(tyOfLocal({LOCALS[I]}:>TypedLocal), PROJS), 0, noMetadataSize)) // TODO: Sus on this rule

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ Slices, `str`s and dynamic types require it, and any `Ty` that `is_sized` does
143143
[preserves-definedness]
144144
```
145145

146+
## Zero-sized types
147+
148+
```k
149+
syntax Bool ::= #zeroSizedType ( TypeInfo ) [function, total]
150+
151+
rule #zeroSizedType(typeInfoTupleType(.Tys)) => true
152+
rule #zeroSizedType(typeInfoStructType(_, _, .Tys, _)) => true
153+
rule #zeroSizedType(typeInfoVoidType) => true
154+
// FIXME: Only unit tuples, empty structs, and void are recognized here; other
155+
// zero-sized types (e.g. single-variant enums, function or closure items,
156+
// newtype wrappers around ZSTs) still fall through because we do not consult
157+
// the layout metadata yet. Update once we rely on machineSize(0).
158+
rule #zeroSizedType(_) => false [owise]
159+
```
160+
146161
```k
147162
endmodule
148163
```

0 commit comments

Comments
 (0)