zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit d676b153a382b686ffc7f6c9fd44e53a32232db9 (tree)
parent 5beb92687b19a99ec3509f810840c7c47f8eaf0a
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sat,  7 Mar 2026 15:00:14 +0000

sema: remove has_compile_errors; crash immediately on all unimplemented paths

Replace all 42 SET_ERROR/has_compile_errors patterns with UNIMPLEMENTED(),
which calls fprintf+exit(1) and uses while(1) to satisfy TCC's control-flow
analysis (TCC does not recognize exit() as noreturn).

Remove both bail-out checks on has_compile_errors. Since zig0 only processes
valid, compiling Zig code, any previously-silent error path is a bug in the
C implementation and should crash immediately rather than propagate corrupt
state.

Add UNIMPLEMENTED to 9 silent void returns identified as unimplemented paths:
zirBitcast, zirAsNode, semaAnalyzeCall (x2), @This fallback, zirRetType,
zirElemType, zirRef, zirOptionalPayload.

num_passing stays at 0 until zirFieldValComptime is implemented for the
builtin zig_backend field, which every corpus file exercises.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 168++++++++++++++++++++++++++++---------------------------------------------------
1 file changed, 60 insertions(+), 108 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -17,12 +17,14 @@ } \ } while (0) // Crash on unimplemented code paths with file/line info. +// while(1) after exit(1) convinces TCC that control never leaves this macro, +// because TCC does not recognise exit() as noreturn. #define UNIMPLEMENTED(msg) \ do { \ fprintf( \ stderr, "UNIMPLEMENTED: %s:%d: %s\n", __FILE__, __LINE__, (msg)); \ exit(1); \ - } while (0) + } while (1) #define SEMA_AIR_INITIAL_CAP 256 #define SEMA_AIR_EXTRA_INITIAL_CAP 256 @@ -167,8 +169,7 @@ AirInstRef resolveInst(Sema* sema, ZirInstRef zir_ref) { uint32_t zir_inst = zir_ref - ZIR_REF_START_INDEX; AirInstRef result = instMapGet(&sema->inst_map, zir_inst); if (result == AIR_REF_NONE) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } return result; } @@ -980,8 +981,7 @@ static AirInstRef zirLoad(Sema* sema, SemaBlock* block, uint32_t inst) { if (AIR_REF_IS_IP(ptr) && block->is_comptime) { // Comptime load from comptime-known pointer: not yet implemented. // Zig calls pointerDeref(ptr_val, ptr_ty) to get the loaded value. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } TypeIndex ptr_ty = semaTypeOf(sema, ptr); TypeIndex elem_ty = ptrChildType(sema->ip, ptr_ty); @@ -1123,8 +1123,7 @@ emit_runtime:; // Ported from Sema.zig analyzeArithmetic: validate peer type is numeric. // checkArithmeticOp verifies operands are int or float. if (!isNumericType(sema->ip, peer_ty)) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } lhs = semaCoerce(sema, block, peer_ty, lhs); rhs = semaCoerce(sema, block, peer_ty, rhs); @@ -1211,8 +1210,7 @@ static AirInstRef zirNegate(Sema* sema, SemaBlock* block, uint32_t inst) { if (sema->ip->items[ty].tag == IP_KEY_INT_TYPE && !sema->ip->items[ty].data.int_type.signedness) { // "negation of unsigned integer type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Int negation: splat(rhs_ty, 0) then sub(0, operand). @@ -1242,8 +1240,7 @@ static AirInstRef zirNegateWrap(Sema* sema, SemaBlock* block, uint32_t inst) { || (sema->ip->items[ty].tag == IP_KEY_INT_TYPE) || (floatBits(ty) > 0); if (!valid) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } InternPoolKey key; @@ -1277,8 +1274,7 @@ static AirInstRef analyzeBitNot( && sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE); if (!valid_ty && AIR_REF_IS_IP(operand)) { // Non-int/bool type for bitwise NOT — compile error. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Comptime folding: if the operand is a comptime integer, // compute ~value at comptime. @@ -1317,8 +1313,7 @@ static AirInstRef analyzeBitNot( || (operand_ty != IP_INDEX_NONE && sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE); if (!rt_valid) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstData data; @@ -1366,8 +1361,7 @@ static AirInstRef zirIsNonNull(Sema* sema, SemaBlock* block, uint32_t inst) { || (sema->ip->items[op_ty].tag == IP_KEY_PTR_TYPE); if (!nullable && op_ty != TYPE_NONE) { // "expected optional type for is_non_null" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstData data; @@ -1391,8 +1385,7 @@ static AirInstRef zirIsNonErr(Sema* sema, SemaBlock* block, uint32_t inst) { = (sema->ip->items[op_ty].tag == IP_KEY_ERROR_UNION_TYPE); if (!valid_err) { // "expected error union type for is_non_err" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstData data; @@ -1416,8 +1409,7 @@ static AirInstRef zirBoolNot(Sema* sema, SemaBlock* block, uint32_t inst) { TypeIndex op_ty = semaTypeOf(sema, operand); if (op_ty != IP_INDEX_BOOL_TYPE) { // "expected bool type for !" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } AirInstData data; memset(&data, 0, sizeof(data)); @@ -1666,8 +1658,7 @@ static AirInstRef zirAbs(Sema* sema, SemaBlock* block, uint32_t inst) { || (floatBits(operand_ty) > 0); if (!numeric) { // "expected integer, float, or vector of either" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstData data; @@ -1688,8 +1679,7 @@ static AirInstRef zirBitCount( if (sema->ip->items[operand_ty].tag != IP_KEY_INT_TYPE) { // Ported from Sema.zig zirBitCount line 22905: checkIntOrVector. // CLZ/CTZ/popcount requires integer type. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } uint16_t bits = sema->ip->items[operand_ty].data.int_type.bits; uint16_t result_bits = smallestUnsignedBits(bits); @@ -1775,8 +1765,7 @@ static AirInstRef zirByteSwap(Sema* sema, SemaBlock* block, uint32_t inst) { // Ported from Sema.zig zirByteSwap line 22956: checkIntOrVector. // @byteSwap requires integer type. if (sema->ip->items[operand_ty].tag != IP_KEY_INT_TYPE) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Comptime folding: if operand is a comptime-known integer, compute @@ -1791,8 +1780,7 @@ static AirInstRef zirByteSwap(Sema* sema, SemaBlock* block, uint32_t inst) { // Ported from Sema.zig zirByteSwap lines 22958-22964: // bits must be divisible by 8, else compile error. if (bits > 0 && bits % 8 != 0) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } if (bits > 0 && bits % 8 == 0) { // Byte-swap: reverse the bytes. @@ -1842,8 +1830,7 @@ static AirInstRef zirBitReverse(Sema* sema, SemaBlock* block, uint32_t inst) { || (operand_ty != IP_INDEX_NONE && sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE); if (!valid_ty) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Comptime folding for integer operands. @@ -1941,8 +1928,7 @@ static AirInstRef zirCmpEq( // Ported from Sema.zig analyzeCmp line 16620: isSelfComparable. // Equality operators require a comparable type. if (!isComparableType(sema->ip, peer_ty, true)) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_BOOL_FALSE); + UNIMPLEMENTED("error: has_compile_errors path"); } lhs = semaCoerce(sema, block, peer_ty, lhs); rhs = semaCoerce(sema, block, peer_ty, rhs); @@ -2103,8 +2089,7 @@ static AirInstRef zirCmp( // Ported from Sema.zig analyzeCmp line 16620: isSelfComparable. // Comparison operators require a comparable type. if (!isComparableType(sema->ip, peer_ty, false)) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_BOOL_FALSE); + UNIMPLEMENTED("error: has_compile_errors path"); } lhs = semaCoerce(sema, block, peer_ty, lhs); rhs = semaCoerce(sema, block, peer_ty, rhs); @@ -2182,8 +2167,7 @@ static AirInstRef zirDiv(Sema* sema, SemaBlock* block, uint32_t inst) { if (pk.data.int_type.signedness) { // "division with signed integers: must use @divTrunc, // @divFloor, or @divExact" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } air_tag = AIR_INST_DIV_TRUNC; } @@ -2386,8 +2370,7 @@ static AirInstRef zirBitwise( || (sema->ip->items[peer_ty].tag == IP_KEY_INT_TYPE); if (!valid) { // "invalid operands to binary bitwise expression" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } @@ -2438,7 +2421,7 @@ static AirInstRef zirBitcast(Sema* sema, SemaBlock* block, uint32_t inst) { } else { AirInstRef resolved = resolveInst(sema, dest_ty_ref); if (!AIR_REF_IS_IP(resolved)) - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("zirBitcast: dest type is runtime value"); dest_ty = AIR_REF_TO_IP(resolved); } AirInstRef operand = resolveInst(sema, operand_ref); @@ -2450,8 +2433,7 @@ static AirInstRef zirBitcast(Sema* sema, SemaBlock* block, uint32_t inst) { || dest_ty == IP_INDEX_TYPE_TYPE || dest_ty == IP_INDEX_VOID_TYPE || dest_ty == IP_INDEX_NORETURN_TYPE) { // "@bitCast to/from comptime-only or void/noreturn type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Ported from Sema.zig zirBitcast lines 9958-10010: @@ -2463,8 +2445,7 @@ static AirInstRef zirBitcast(Sema* sema, SemaBlock* block, uint32_t inst) { || src_ty == IP_INDEX_TYPE_TYPE || src_ty == IP_INDEX_VOID_TYPE || src_ty == IP_INDEX_NORETURN_TYPE) { // "@bitCast from comptime-only or void/noreturn type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } @@ -2513,8 +2494,7 @@ static AirInstRef analyzeTyOpCast( || (sema->ip->items[dest_ty].tag == IP_KEY_INT_TYPE); if (!src_is_int || !dst_is_int) { // "expected integer type for intcast/truncate" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstData data; @@ -2575,13 +2555,11 @@ static AirInstRef zirFloatCast(Sema* sema, SemaBlock* block, uint32_t inst) { // dest must be a concrete float type; operand must be float. if (dst_bits == 0 && dest_ty != IP_INDEX_COMPTIME_FLOAT_TYPE) { // "@floatCast destination is not a float type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } if (src_bits == 0 && operand_ty != IP_INDEX_COMPTIME_FLOAT_TYPE) { // "@floatCast source is not a float type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } AirInstTag air_tag; @@ -2691,23 +2669,20 @@ static AirInstRef zirShl( // Ported from Sema.zig zirShl/zirShr exact overflow check: // Check if shift amount >= bit width. if (shift >= bits) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } if (bits <= 64 && shift > 0) { if (air_tag == AIR_INST_SHL_EXACT) { // Check if non-zero bits were shifted out (left). uint64_t lost_bits_mask = UINT64_MAX << (bits - shift); if (lhs_lo & lost_bits_mask) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } else { // SHR_EXACT: check if non-zero bits shifted off right. uint64_t lost_bits_mask = (UINT64_C(1) << shift) - 1; if (lhs_lo & lost_bits_mask) { - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } } @@ -2799,7 +2774,7 @@ static AirInstRef zirAsNode(Sema* sema, SemaBlock* block, uint32_t inst) { return resolveInst(sema, operand_ref); } if (!AIR_REF_IS_IP(resolved)) { - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("zirAs: dest type is runtime value"); } dest_ty = AIR_REF_TO_IP(resolved); } @@ -6702,7 +6677,7 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, zirDeinit(&cr->import_zir); astDeinit(&cr->import_ast); } - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("semaAnalyzeCall: function has no body"); } // Type-returning functions (return `type`): evaluate via comptime @@ -6770,7 +6745,8 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, if (AIR_REF_IS_IP(honest_result) && AIR_REF_TO_IP(honest_result) != IP_INDEX_VOID_VALUE) return honest_result; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED( + "semaAnalyzeCall: comptime type-call evaluation failed"); } } @@ -6927,8 +6903,7 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, // must not prevent the actual function body from being analyzed. // Ported from Sema.zig analyzeCall where ret_ty resolution is // a best-effort step that doesn't propagate failures. - bool saved_compile_errors = sema->has_compile_errors; - sema->has_compile_errors = false; + // (has_compile_errors save removed — we crash on all errors) (void)analyzeBodyInner( sema, &ct_block, rtb, func_info.ret_ty_body_len); @@ -6941,7 +6916,7 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, } semaBlockDeinit(&ct_block); sema->comptime_break_inst = saved_cbi; - sema->has_compile_errors = saved_compile_errors; + // (has_compile_errors restore removed) } // Handle case where return type is a param ref (e.g. `fn absv(comptime // ST: type, a: ST) ST`). The ret_ty_ref points to a param instruction; @@ -7376,11 +7351,7 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, || ptag == ZIR_INST_PARAM_ANYTYPE || ptag == ZIR_INST_PARAM_ANYTYPE_COMPTIME) { if (param_idx >= args_len) { - sema->has_compile_errors = true; - free(sema->inst_map.items); - sema->inst_map = saved_inst_map; - block->is_comptime = saved_is_comptime; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Coerce typed comptime params to their declared type. // Ported from Sema.zig analyzeArg (line 7153): args are coerced @@ -7774,8 +7745,7 @@ static AirInstRef semaAnalyzeCall(Sema* sema, SemaBlock* block, uint32_t inst, // in a child block and emits dbg_inline_block. static AirInstRef zirCall( Sema* sema, SemaBlock* block, uint32_t inst, bool is_field_call) { - if (sema->has_compile_errors) - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + uint32_t payload_index = sema->code.inst_datas[inst].pl_node.payload_index; // Parse Call/FieldCall extra data. @@ -9869,8 +9839,7 @@ static AirInstRef zirBitSizeOf(Sema* sema, uint32_t inst) { || type_ip == IP_INDEX_NORETURN_TYPE || type_ip == IP_INDEX_UNDEFINED_TYPE) { // "no size available for type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // void, type, comptime_int, comptime_float, enum_literal have 0 // bits. @@ -10268,8 +10237,7 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) { } if (struct_ty == IP_INDEX_VOID_TYPE) { // Ported from Sema.zig fieldPtr: unresolved struct type → error. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } uint32_t fidx = 0; @@ -10277,8 +10245,7 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) { = lookupStructField(sema, struct_ty, field_name, &fidx); if (!si) { // Ported from Sema.zig fieldPtr: field not found in struct → error. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } // Result type is pointer-to-field-type. @@ -10553,7 +10520,7 @@ static uint8_t analyzeBodyRuntimeBreak( // --- zirRetImplicit --- // Ported from src/Sema.zig zirRetImplicit / analyzeRet. -static void zirRetImplicit(Sema* sema, SemaBlock* block, uint32_t inst) { +static void zirRetImplicit(const Sema* sema, SemaBlock* block, uint32_t inst) { (void)inst; // Ported from Sema.zig zirRetImplicit: validate return type is void. // Zig lines 18690-18710: noreturn or non-void return type is an error. @@ -10562,8 +10529,7 @@ static void zirRetImplicit(Sema* sema, SemaBlock* block, uint32_t inst) { // Function has non-void return type but uses implicit return. // This is a compile error in Zig: // "function with non-void return type implicitly returns" - sema->has_compile_errors = true; - return; + UNIMPLEMENTED("error: has_compile_errors path"); } AirInstRef operand = AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); if (block->inlining) { @@ -10597,8 +10563,7 @@ static void zirRetNode(Sema* sema, SemaBlock* block, uint32_t inst) { // Ported from Sema.zig zirRetNode: fn_ret_ty must be known. // If TYPE_NONE, the return type was not resolved — compile error. if (sema->fn_ret_ty == TYPE_NONE) { - sema->has_compile_errors = true; - return; + UNIMPLEMENTED("error: has_compile_errors path"); } operand = semaCoerce(sema, block, sema->fn_ret_ty, operand); if (block->inlining) { @@ -10710,7 +10675,7 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) { uint32_t ns_idx = sema->zcu->file_namespaces[sema->file_idx]; return AIR_REF_FROM_IP(sema->zcu->namespaces[ns_idx].owner_type); } - return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + UNIMPLEMENTED("zirExtended/@This: no file context"); } if (opcode == ZIR_EXT_BRANCH_HINT) { uint32_t payload_index = sema->code.inst_datas[inst].extended.operand; @@ -11002,8 +10967,7 @@ static AirInstRef zirMinMax(Sema* sema, SemaBlock* block, uint32_t inst) { || (floatBits(peer_ty) > 0); if (!numeric) { // "@min/@max on non-numeric type" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } } AirInstRef c_lhs = semaCoerce(sema, block, peer_ty, min_lhs); @@ -11104,7 +11068,7 @@ static AirInstRef zirRetPtr(Sema* sema, SemaBlock* block) { static AirInstRef zirRetType(Sema* sema) { if (sema->fn_ret_ty != TYPE_NONE) return AIR_REF_FROM_IP(sema->fn_ret_ty); - return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + UNIMPLEMENTED("zirRetType: fn_ret_ty not set"); } // --- zirElemType --- @@ -11113,7 +11077,7 @@ static AirInstRef zirElemType(Sema* sema, uint32_t inst) { ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand; AirInstRef resolved = resolveInst(sema, operand_ref); if (!AIR_REF_IS_IP(resolved)) - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("zirElemType: operand not a comptime type"); TypeIndex ptr_ty = AIR_REF_TO_IP(resolved); TypeIndex elem_ty = ptrChildType(sema->ip, ptr_ty); return AIR_REF_FROM_IP(elem_ty); @@ -11183,9 +11147,7 @@ static void zirBlockComptime(Sema* sema, SemaBlock* block, uint32_t inst) { // Ported from Sema.zig block_comptime: body must end with break. // If body completed without a break, the block is ill-formed. // Map to void and propagate error so callers see the failure. - sema->has_compile_errors = true; - instMapPut( - &sema->inst_map, inst, AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE)); + UNIMPLEMENTED("error: has_compile_errors path"); } semaBlockDeinit(&ct_block); } @@ -11201,14 +11163,13 @@ static AirInstRef zirRef(Sema* sema, uint32_t inst) { // Ported from Sema.zig analyzeRef: runtime ref path not implemented. // Upstream creates alloc+store+ref for runtime values; C is // comptime-only. - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } InternPoolIndex val = AIR_REF_TO_IP(operand); InternPoolIndex val_ty = ipTypeOf(sema->ip, val); if (val_ty == IP_INDEX_NONE) - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("zirRef: comptime IP value has no type"); // Create *const T pointer type. InternPoolIndex ptr_ty = internPtrConst(sema, val_ty); @@ -11292,8 +11253,7 @@ static void zirAlloc(Sema* sema, SemaBlock* block, uint32_t inst) { AirInstRef resolved = resolveInst(sema, type_ref); if (!AIR_REF_IS_IP(resolved)) { // Ported from Sema.zig zirAlloc: type must be resolvable. - sema->has_compile_errors = true; - return; + UNIMPLEMENTED("error: has_compile_errors path"); } TypeIndex elem_ty = AIR_REF_TO_IP(resolved); InternPoolKey key; @@ -12077,8 +12037,7 @@ static bool zirCondbr(Sema* sema, SemaBlock* block, uint32_t inst) { // If it doesn't, we have an unresolvable comptime condition — bail // out rather than falling through to runtime codegen. if (block->is_comptime) { - sema->has_compile_errors = true; - return true; + UNIMPLEMENTED("error: has_compile_errors path"); } SemaBlock then_block; @@ -12267,15 +12226,14 @@ static AirInstRef zirOptionalPayload( InternPoolIndex operand_ip = AIR_REF_TO_IP(operand); InternPoolIndex operand_ty = ipTypeOf(sema->ip, operand_ip); if (operand_ty == IP_INDEX_NONE) - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("zirOptionalPayload: comptime IP value has no type"); // Get the optional child type. InternPoolKey ty_key = sema->ip->items[operand_ty]; if (ty_key.tag != IP_KEY_OPT_TYPE) { // Ported from Sema.zig zirOptionalPayload lines 8587-8608: // "expected optional type, found '{f}'" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } InternPoolIndex child_type = ty_key.data.opt_type; @@ -12319,8 +12277,7 @@ static AirInstRef zirIntFromEnum(Sema* sema, SemaBlock* block, uint32_t inst) { if (sema->ip->items[operand_ty].tag != IP_KEY_ENUM_TYPE && sema->ip->items[operand_ty].tag != IP_KEY_UNION_TYPE) { // "expected enum or tagged union, found '{f}'" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } AirInstData data; memset(&data, 0, sizeof(data)); @@ -12365,8 +12322,7 @@ static AirInstRef zirErrUnionPayload( // operand must be error union type. if (sema->ip->items[eu_ty].tag != IP_KEY_ERROR_UNION_TYPE) { // "expected error union type, found '{f}'" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } TypeIndex payload_ty = sema->ip->items[eu_ty].data.error_union_type.payload; @@ -12389,8 +12345,7 @@ static AirInstRef zirErrUnionCode( // operand must be error union type. if (sema->ip->items[eu_ty].tag != IP_KEY_ERROR_UNION_TYPE) { // "expected error union type, found '{f}'" - sema->has_compile_errors = true; - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + UNIMPLEMENTED("error: has_compile_errors path"); } TypeIndex err_ty = sema->ip->items[eu_ty].data.error_union_type.error_set; AirInstData data; @@ -12413,10 +12368,7 @@ bool analyzeBodyInner( uint32_t i = 0; while (i < body_len) { - // Bail out early if we've hit a compile error to avoid cascading - // failures (e.g. null dereferences from void fallback values). - if (sema->has_compile_errors) - return true; + uint32_t inst = body[i]; ZirInstTag inst_tag = sema->code.inst_tags[inst]; switch (inst_tag) {