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>
This commit is contained in:
168
stage0/sema.c
168
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) {
|
||||
|
||||
Reference in New Issue
Block a user