@@ -402,10 +402,14 @@ def _decode_enum_multiple(
402402 # ---
403403 types : Mapping [Ty , TypeMetadata ],
404404) -> Value :
405- assert len (offsets ) == 1 , 'Assumed offsets to only contain the tag offset'
406- assert tag_field == 0 , 'Assumed tag field to be zero accordingly'
407- tag_offset = offsets [tag_field ]
408- tag_value , width = _extract_tag (data = data , tag_offset = tag_offset , tag = tag )
405+ if offsets :
406+ assert 0 <= tag_field < len (offsets ), 'Expected tag_field to point to an existing offset'
407+ tag_offset_in_bytes = offsets [tag_field ].in_bytes
408+ else :
409+ # Fieldless enums can omit offsets in Stable MIR; their tag still starts at byte 0.
410+ assert tag_field == 0 , 'Expected empty offsets only when tag_field is zero'
411+ tag_offset_in_bytes = 0
412+ tag_value , width = _extract_tag (data = data , tag_offset_in_bytes = tag_offset_in_bytes , tag = tag )
409413 discriminant = tag_encoding .decode (tag_value , width = width )
410414
411415 try :
@@ -440,7 +444,7 @@ def _decode_fields(
440444 return res
441445
442446
443- def _extract_tag (* , data : bytes , tag_offset : MachineSize , tag : Scalar ) -> tuple [int , IntegerLength ]:
447+ def _extract_tag (* , data : bytes , tag_offset_in_bytes : int , tag : Scalar ) -> tuple [int , IntegerLength ]:
444448 match tag :
445449 case Initialized (
446450 value = PrimitiveInt (
@@ -449,9 +453,8 @@ def _extract_tag(*, data: bytes, tag_offset: MachineSize, tag: Scalar) -> tuple[
449453 ),
450454 valid_range = _,
451455 ):
452- # Stable MIR enum discriminants are represented against the raw tag bits.
453- # Use unsigned decoding even when the scalar metadata marks the tag as signed.
454- tag_data = data [tag_offset .in_bytes : tag_offset .in_bytes + length .value ]
456+ tag_data = data [tag_offset_in_bytes : tag_offset_in_bytes + length .value ]
457+ # For enum-tag decoding we match Stable MIR discriminants in wrapped form.
455458 tag_value = int .from_bytes (tag_data , byteorder = 'little' , signed = False )
456459 return tag_value , length
457460 # special case: niche-encoded optional pointer, None == 0x00000000
0 commit comments