sema: add runtime path to zirOptionalPayload
Previously, zirOptionalPayload only handled comptime optional unwrapping. Runtime optional values (AIR instructions) returned void instead of emitting proper AIR code. Add runtime path: if operand is a runtime AIR instruction with optional type, get the payload child type and emit AIR_INST_OPTIONAL_PAYLOAD with ty_op layout. Also add AIR_INST_OPTIONAL_PAYLOAD to semaTypeOf ty_op group. Ported from Sema.zig zirOptionalPayload runtime path. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -592,6 +592,7 @@ static TypeIndex semaTypeOf(Sema* sema, AirInstRef ref) {
|
||||
case AIR_INST_INTCAST:
|
||||
case AIR_INST_TRUNC:
|
||||
case AIR_INST_LOAD:
|
||||
case AIR_INST_OPTIONAL_PAYLOAD:
|
||||
case AIR_INST_NOT:
|
||||
case AIR_INST_FPTRUNC:
|
||||
case AIR_INST_FPEXT:
|
||||
@@ -11595,15 +11596,27 @@ static AirInstRef zirCoercePtrElemTy(Sema* sema, uint32_t inst) {
|
||||
return resolveInst(sema, val_ref);
|
||||
}
|
||||
|
||||
// zirOptionalPayload: extract value payload from a comptime optional.
|
||||
// zirOptionalPayload: extract value payload from an optional.
|
||||
// Ported from src/Sema.zig zirOptionalPayload.
|
||||
// For comptime: resolves operand, gets optional child type, extracts payload.
|
||||
static AirInstRef zirOptionalPayload(Sema* sema, uint32_t inst) {
|
||||
// Comptime: resolves operand, gets optional child type, extracts payload.
|
||||
// Runtime: emits AIR_INST_OPTIONAL_PAYLOAD with the payload type.
|
||||
static AirInstRef zirOptionalPayload(
|
||||
Sema* sema, SemaBlock* block, uint32_t inst) {
|
||||
ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand;
|
||||
AirInstRef operand = resolveInst(sema, operand_ref);
|
||||
|
||||
if (!AIR_REF_IS_IP(operand))
|
||||
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
|
||||
if (!AIR_REF_IS_IP(operand)) {
|
||||
// Runtime optional: get child type and emit optional_payload.
|
||||
TypeIndex opt_ty = semaTypeOf(sema, operand);
|
||||
TypeIndex child_ty = IP_INDEX_VOID_TYPE;
|
||||
if (sema->ip->items[opt_ty].tag == IP_KEY_OPT_TYPE)
|
||||
child_ty = sema->ip->items[opt_ty].data.opt_type;
|
||||
AirInstData data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.ty_op.ty_ref = AIR_REF_FROM_IP(child_ty);
|
||||
data.ty_op.operand = operand;
|
||||
return semaAddInst(block, AIR_INST_OPTIONAL_PAYLOAD, data);
|
||||
}
|
||||
|
||||
InternPoolIndex operand_ip = AIR_REF_TO_IP(operand);
|
||||
InternPoolIndex operand_ty = ipTypeOf(sema->ip, operand_ip);
|
||||
@@ -12401,7 +12414,8 @@ bool analyzeBodyInner(
|
||||
// Ported from src/Sema.zig zirOptionalPayload.
|
||||
case ZIR_INST_OPTIONAL_PAYLOAD_SAFE:
|
||||
case ZIR_INST_OPTIONAL_PAYLOAD_UNSAFE:
|
||||
instMapPut(&sema->inst_map, inst, zirOptionalPayload(sema, inst));
|
||||
instMapPut(
|
||||
&sema->inst_map, inst, zirOptionalPayload(sema, block, inst));
|
||||
i++;
|
||||
continue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user