diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/data.md b/kmir/src/kmir/kdist/mir-semantics/rt/data.md index 5839521b4..7fe8f847f 100644 --- a/kmir/src/kmir/kdist/mir-semantics/rt/data.md +++ b/kmir/src/kmir/kdist/mir-semantics/rt/data.md @@ -359,6 +359,14 @@ These helpers mark down, as we traverse the projection, what `Place` we are curr rule #buildUpdate(Aggregate(variantIdx(0), ListItem(VALUE) .List), CtxWrapStruct CTXS) => #buildUpdate(VALUE, CTXS) + // Reinterpret union payloads through the accessed field type. + // This keeps the underlying bits and switches signedness/width for integer fields. + syntax Value ::= #unionFieldRead ( Value , Ty ) [function, total] + rule #unionFieldRead(Integer(VAL, WIDTH, _SIGNEDNESS), TY) + => #intAsType(VAL, WIDTH, #numTypeOf(lookupTy(TY))) + requires #isIntType(lookupTy(TY)) + rule #unionFieldRead(VAL, _TY) => VAL [owise] + syntax StackFrame ::= #updateStackLocal ( StackFrame, Int, Value ) [function] @@ -512,16 +520,16 @@ The following rule resolves this situation by using the head element. #### Unions ```k - // Case: Union is in same state as field projection + // Union field reads reuse the stored payload and reinterpret integer fields through the accessed type. rule #traverseProjection( DEST, - Union(FIELD_IDX, ARG), + Union(_ACTIVE_FIELD_IDX, ARG), projectionElemField(FIELD_IDX, TY) PROJS, CTXTS ) => #traverseProjection( DEST, - ARG, + #unionFieldRead(ARG, TY), PROJS, CtxFieldUnion(FIELD_IDX, ARG, TY) CTXTS ) @@ -529,7 +537,7 @@ The following rule resolves this situation by using the head element. [preserves-definedness] - // TODO: Case: Union is in different state as field projection + // Union field reads are permitted regardless of the active field. ``` #### Ranges diff --git a/kmir/src/tests/integration/data/prove-rs/show/unions-fail.main.expected b/kmir/src/tests/integration/data/prove-rs/show/unions-fail.main.expected deleted file mode 100644 index dea9bd948..000000000 --- a/kmir/src/tests/integration/data/prove-rs/show/unions-fail.main.expected +++ /dev/null @@ -1,16 +0,0 @@ - -┌─ 1 (root, init) -│ #execTerminator ( terminator ( ... kind: terminatorKindCall ( ... func: operandC -│ span: 0 -│ -│ (76 steps) -└─ 3 (stuck, leaf) - #traverseProjection ( toLocal ( 1 ) , Union ( fieldIdx ( 0 ) , Integer ( -1 , 8 - function: main - span: 59 - - -┌─ 2 (root, leaf, target, terminal) -│ #EndProgram ~> .K - - diff --git a/kmir/src/tests/integration/data/prove-rs/unions-fail.rs b/kmir/src/tests/integration/data/prove-rs/unions.rs similarity index 100% rename from kmir/src/tests/integration/data/prove-rs/unions-fail.rs rename to kmir/src/tests/integration/data/prove-rs/unions.rs diff --git a/kmir/src/tests/integration/test_integration.py b/kmir/src/tests/integration/test_integration.py index 14b5221c3..ce7094256 100644 --- a/kmir/src/tests/integration/test_integration.py +++ b/kmir/src/tests/integration/test_integration.py @@ -59,7 +59,6 @@ 'transmute-u8-to-enum-fail', 'assert-inhabited-fail', 'iterator-simple', - 'unions-fail', 'transmute-maybe-uninit-fail', 'ptr-through-wrapper-fail', 'test_offset_from-fail',