Skip to content
19 changes: 19 additions & 0 deletions kmir/src/kmir/kdist/mir-semantics/rt/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ Constant operands are simply decoded according to their type.
...
</k>
requires typeInfoVoidType =/=K lookupTy(TY)

// Fallback for zero-sized constants whose type metadata was not emitted.
rule <k> operandConstant(constOperand(_, _, mirConst(constantKindZeroSized, TY, _)))
=> Aggregate(variantIdx(0), .List)
...
</k>
requires typeInfoVoidType ==K lookupTy(TY)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually see this case? (no metadata available)
We have rules for ZeroSized constants with known metadata so if we find this necessary we should investigate it more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

```

### Copying and Moving
Expand Down Expand Up @@ -1088,6 +1095,18 @@ This eliminates any `Deref` projections from the place, and also resolves `Index
// rule #projectionsFor(CtxPointerOffset(OFFSET, ORIGIN_LENGTH) CTXS, PROJS) => #projectionsFor(CTXS, projectionElemSubslice(OFFSET, ORIGIN_LENGTH, false) PROJS)
rule #projectionsFor(CtxPointerOffset( _, OFFSET, ORIGIN_LENGTH) CTXS, PROJS) => #projectionsFor(CTXS, PointerOffset(OFFSET, ORIGIN_LENGTH) PROJS)

// Borrowing a zero-sized local that is still `NewLocal`: initialise it, then reuse the regular rule.
rule <k> rvalueRef(REGION, KIND, place(local(I), PROJS))
=> #forceSetLocal(local(I), Aggregate(variantIdx(0), .List))
~> rvalueRef(REGION, KIND, place(local(I), PROJS))
...
</k>
<locals> LOCALS </locals>
requires 0 <=Int I andBool I <Int size(LOCALS)
andBool isNewLocal(LOCALS[I])
andBool #zeroSizedType(lookupTy(tyOfLocal(getLocal(LOCALS, I))))
[preserves-definedness] // valid list indexing checked, zero-sized locals materialise trivially

Comment on lines 1067 to 1085
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are very useful rules to handle the cases described in #675 .
Maybe we could call #decodeConstant instead of assuming an Aggregate and inserting it directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved

rule <k> rvalueRef(_REGION, KIND, place(local(I), PROJS))
=> #traverseProjection(toLocal(I), getValue(LOCALS, I), PROJS, .Contexts)
~> #forRef(#mutabilityOf(KIND), metadata(#metadataSize(tyOfLocal({LOCALS[I]}:>TypedLocal), PROJS), 0, noMetadataSize)) // TODO: Sus on this rule
Expand Down
15 changes: 15 additions & 0 deletions kmir/src/kmir/kdist/mir-semantics/rt/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ Slices, `str`s and dynamic types require it, and any `Ty` that `is_sized` does
[preserves-definedness]
```

## Zero-sized types

```k
syntax Bool ::= #zeroSizedType ( TypeInfo ) [function, total]

rule #zeroSizedType(typeInfoTupleType(.Tys)) => true
rule #zeroSizedType(typeInfoStructType(_, _, .Tys, _)) => true
rule #zeroSizedType(typeInfoVoidType) => true
// FIXME: Only unit tuples, empty structs, and void are recognized here; other
// zero-sized types (e.g. single-variant enums, function or closure items,
// newtype wrappers around ZSTs) still fall through because we do not consult
// the layout metadata yet. Update once we rely on machineSize(0).
rule #zeroSizedType(_) => false [owise]
```

```k
endmodule
```
Loading