diff --git a/kmir/src/kmir/decoding.py b/kmir/src/kmir/decoding.py index 4d0dc95fb..27a2dc019 100644 --- a/kmir/src/kmir/decoding.py +++ b/kmir/src/kmir/decoding.py @@ -445,10 +445,12 @@ def _extract_tag(*, data: bytes, tag_offset: MachineSize, tag: Scalar) -> tuple[ case Initialized( value=PrimitiveInt( length=length, - signed=False, + signed=_, ), valid_range=_, ): + # Stable MIR enum discriminants are represented against the raw tag bits. + # Use unsigned decoding even when the scalar metadata marks the tag as signed. tag_data = data[tag_offset.in_bytes : tag_offset.in_bytes + length.value] tag_value = int.from_bytes(tag_data, byteorder='little', signed=False) return tag_value, length diff --git a/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.expected b/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.expected new file mode 100644 index 000000000..8916e2b4d --- /dev/null +++ b/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.expected @@ -0,0 +1 @@ +Aggregate ( variantIdx ( 1 ) , .List ) diff --git a/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.json b/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.json new file mode 100644 index 000000000..3696e0d04 --- /dev/null +++ b/kmir/src/tests/integration/data/decode-value/enum-3-variants-0-fields-signed-tag.json @@ -0,0 +1,138 @@ +{ + "bytes": [ + 0 + ], + "types": [], + "typeInfo": { + "EnumType": { + "name": "OrderingLike", + "adt_def": 72, + "discriminants": [ + 255, + 0, + 1 + ], + "fields": [ + [], + [], + [] + ], + "layout": { + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "value": { + "Int": { + "length": "I8", + "signed": true + } + }, + "valid_range": { + "start": 255, + "end": 1 + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "variants": { + "Single": { + "index": 0 + } + }, + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "size": { + "num_bits": 8 + } + }, + { + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "variants": { + "Single": { + "index": 1 + } + }, + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "size": { + "num_bits": 8 + } + }, + { + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "variants": { + "Single": { + "index": 2 + } + }, + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "size": { + "num_bits": 8 + } + } + ] + } + }, + "abi": { + "Scalar": { + "Initialized": { + "value": { + "Int": { + "length": "I8", + "signed": true + } + }, + "valid_range": { + "start": 255, + "end": 1 + } + } + } + }, + "abi_align": 1, + "size": { + "num_bits": 8 + } + } + } + } +} diff --git a/kmir/src/tests/integration/data/prove-rs/show/transmute-u8-to-enum-changed-discriminant-signed-fail.main.expected b/kmir/src/tests/integration/data/prove-rs/show/transmute-u8-to-enum-changed-discriminant-signed-fail.main.expected deleted file mode 100644 index ce7aaeddb..000000000 --- a/kmir/src/tests/integration/data/prove-rs/show/transmute-u8-to-enum-changed-discriminant-signed-fail.main.expected +++ /dev/null @@ -1,15 +0,0 @@ - -┌─ 1 (root, init) -│ #execTerminator ( terminator ( ... kind: terminatorKindCall ( ... func: operandC -│ span: 0 -│ -│ (102 steps) -└─ 3 (stuck, leaf) - #traverseProjection ( toLocal ( 2 ) , thunk ( #decodeConstant ( constantKindAllo - span: 153 - - -┌─ 2 (root, leaf, target, terminal) -│ #EndProgram ~> .K - - diff --git a/kmir/src/tests/integration/data/prove-rs/transmute-u8-to-enum-changed-discriminant-signed-fail.rs b/kmir/src/tests/integration/data/prove-rs/transmute-u8-to-enum-changed-discriminant-signed.rs similarity index 100% rename from kmir/src/tests/integration/data/prove-rs/transmute-u8-to-enum-changed-discriminant-signed-fail.rs rename to kmir/src/tests/integration/data/prove-rs/transmute-u8-to-enum-changed-discriminant-signed.rs diff --git a/kmir/src/tests/integration/test_integration.py b/kmir/src/tests/integration/test_integration.py index a5f470208..0de9ce097 100644 --- a/kmir/src/tests/integration/test_integration.py +++ b/kmir/src/tests/integration/test_integration.py @@ -54,7 +54,6 @@ 'assume-cheatcode-conflict-fail', 'raw-ptr-cast-fail', 'transmute-u8-to-enum-fail', - 'transmute-u8-to-enum-changed-discriminant-signed-fail', 'assert-inhabited-fail', 'iterator-simple', 'unions-fail',