diff --git a/stage0/sema.c b/stage0/sema.c index d47c865ddc..bd3c43ef7d 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -610,6 +610,10 @@ static TypeIndex semaTypeOf(Sema* sema, AirInstRef ref) { case AIR_INST_BYTE_SWAP: case AIR_INST_BIT_REVERSE: case AIR_INST_ABS: + case AIR_INST_UNWRAP_ERRUNION_PAYLOAD: + case AIR_INST_UNWRAP_ERRUNION_ERR: + case AIR_INST_UNWRAP_ERRUNION_PAYLOAD_PTR: + case AIR_INST_UNWRAP_ERRUNION_ERR_PTR: case AIR_INST_NEG: case AIR_INST_NEG_OPTIMIZED: case AIR_INST_DBG_INLINE_BLOCK: @@ -11926,6 +11930,44 @@ static AirInstRef zirOptionalPayload( return AIR_REF_FROM_IP(payload_ip); } +// zirErrUnionPayload: extract payload from error union (unsafe path). +// Ported from src/Sema.zig zirErrUnionPayload → analyzeErrUnionPayload. +// Runtime: emit AIR_INST_UNWRAP_ERRUNION_PAYLOAD. +static AirInstRef zirErrUnionPayload( + Sema* sema, SemaBlock* block, uint32_t inst) { + ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand; + AirInstRef operand = resolveInst(sema, operand_ref); + TypeIndex eu_ty = semaTypeOf(sema, operand); + // Get the payload type from the error union type. + TypeIndex payload_ty = IP_INDEX_VOID_TYPE; + if (sema->ip->items[eu_ty].tag == IP_KEY_ERROR_UNION_TYPE) + payload_ty = sema->ip->items[eu_ty].data.error_union_type.payload; + AirInstData data; + memset(&data, 0, sizeof(data)); + data.ty_op.ty_ref = AIR_REF_FROM_IP(payload_ty); + data.ty_op.operand = operand; + return semaAddInst(block, AIR_INST_UNWRAP_ERRUNION_PAYLOAD, data); +} + +// zirErrUnionCode: extract error code from error union. +// Ported from src/Sema.zig zirErrUnionCode. +// Runtime: emit AIR_INST_UNWRAP_ERRUNION_ERR. +static AirInstRef zirErrUnionCode( + Sema* sema, SemaBlock* block, uint32_t inst) { + ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand; + AirInstRef operand = resolveInst(sema, operand_ref); + TypeIndex eu_ty = semaTypeOf(sema, operand); + // Get the error set type from the error union type. + TypeIndex err_ty = IP_INDEX_VOID_TYPE; + if (sema->ip->items[eu_ty].tag == IP_KEY_ERROR_UNION_TYPE) + err_ty = sema->ip->items[eu_ty].data.error_union_type.error_set; + AirInstData data; + memset(&data, 0, sizeof(data)); + data.ty_op.ty_ref = AIR_REF_FROM_IP(err_ty); + data.ty_op.operand = operand; + return semaAddInst(block, AIR_INST_UNWRAP_ERRUNION_ERR, data); +} + // --- analyzeBodyInner --- // Ported from src/Sema.zig analyzeBodyInner. // Main dispatch loop: iterates over ZIR instructions in a body and @@ -12742,6 +12784,22 @@ bool analyzeBodyInner( i++; continue; + // err_union_payload: extract payload from error union. + case ZIR_INST_ERR_UNION_PAYLOAD_UNSAFE: + case ZIR_INST_ERR_UNION_PAYLOAD_UNSAFE_PTR: + instMapPut( + &sema->inst_map, inst, zirErrUnionPayload(sema, block, inst)); + i++; + continue; + + // err_union_code: extract error code from error union. + case ZIR_INST_ERR_UNION_CODE: + case ZIR_INST_ERR_UNION_CODE_PTR: + instMapPut( + &sema->inst_map, inst, zirErrUnionCode(sema, block, inst)); + i++; + continue; + // Validation-only instructions: no value produced, no AIR emitted. // These validate preconditions but don't produce useful values. case ZIR_INST_VALIDATE_ARRAY_INIT_TY: