diff --git a/stage0/sema.c b/stage0/sema.c index 23a73f89b5..f593f01a32 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -11590,10 +11590,38 @@ static AirInstRef zirIntType(Sema* sema, uint32_t inst) { // --- zirCoercePtrElemTy --- // Ported from src/Sema.zig zirCoercePtrElemTy. -static AirInstRef zirCoercePtrElemTy(Sema* sema, uint32_t inst) { +// Coerces the RHS value to the element type of the LHS pointer. +// For single-pointer (.one) types: coerce to elem_ty. +// For other cases: return value unchanged. +static AirInstRef zirCoercePtrElemTy( + Sema* sema, SemaBlock* block, uint32_t inst) { uint32_t payload_index = sema->code.inst_datas[inst].pl_node.payload_index; + ZirInstRef ptr_ty_ref = sema->code.extra[payload_index]; ZirInstRef val_ref = sema->code.extra[payload_index + 1]; - return resolveInst(sema, val_ref); + AirInstRef uncoerced = resolveInst(sema, val_ref); + + // Resolve the pointer type. + AirInstRef ptr_ty_air; + if (ptr_ty_ref < ZIR_REF_START_INDEX) { + ptr_ty_air = AIR_REF_FROM_IP(ptr_ty_ref); + } else { + ptr_ty_air = resolveInst(sema, ptr_ty_ref); + } + if (!AIR_REF_IS_IP(ptr_ty_air)) + return uncoerced; + TypeIndex ptr_ty = AIR_REF_TO_IP(ptr_ty_air); + + // For pointer types, get the element type and coerce. + // Ported from Sema.zig zirCoercePtrElemTy .one case. + if (sema->ip->items[ptr_ty].tag == IP_KEY_PTR_TYPE) { + TypeIndex elem_ty = sema->ip->items[ptr_ty].data.ptr_type.child; + // Don't coerce to anyopaque — pointer will handle it. + if (elem_ty != IP_INDEX_ANYOPAQUE_TYPE + && elem_ty != IP_INDEX_VOID_TYPE) { + return semaCoerce(sema, block, elem_ty, uncoerced); + } + } + return uncoerced; } // zirOptionalPayload: extract value payload from an optional. @@ -12405,7 +12433,8 @@ bool analyzeBodyInner( continue; case ZIR_INST_COERCE_PTR_ELEM_TY: - instMapPut(&sema->inst_map, inst, zirCoercePtrElemTy(sema, inst)); + instMapPut( + &sema->inst_map, inst, zirCoercePtrElemTy(sema, block, inst)); i++; continue;