zig

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

commit c2b0d0242e00077b4a58a8b320fe6ec26753508a (tree)
parent 97285975d522e86338d6e9c38bed3a0f4a4e9dad
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Fri, 20 Feb 2026 16:29:06 +0000

sema: enable neghf2.zig with cross-module comptime evaluation

Implement comptime evaluation of fneg's body from common.zig:
- block_comptime handler: evaluate body, map break_inline result
- typeof/typeof_builtin: resolve to param type for anytype
- type_info: extract float bits from type
- field_val: comptime field access on type_info results
- reify/struct_init/decl_literal: reconstruct int type from bits
- as_node/bitcast: handle comptime-resolved type refs
- dbg_var_val: skip comptime-only values (types, comptime_int)
- int_comptime handler for cross-module comptime integer literals

neghf2.zig corpus test now passes.

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

Diffstat:
Mstage0/sema.c | 471++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mstage0/stages_test.zig | 2+-
2 files changed, 454 insertions(+), 19 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -128,10 +128,13 @@ static void instMapPut(InstMap* map, uint32_t zir_inst, AirInstRef ref) { // --- Comptime tracker helpers --- // Track comptime type-info values for cross-module inline evaluation. -// tag: 0=none, 1=type_info(type), 2=float_info(bits) +// tag: 0=none, 1=type_info(type), 2=float_info(bits), +// 3=int_info(signedness<<16|bits), 4=reify_int(int_info_ip) #define CT_TAG_NONE 0 #define CT_TAG_TYPE_INFO 1 #define CT_TAG_FLOAT_INFO 2 +#define CT_TAG_INT_INFO 3 +#define CT_TAG_REIFY_INT 4 static void ctTrack(Sema* sema, InternPoolIndex ip_idx, uint8_t tag_val, uint32_t val) { @@ -257,6 +260,9 @@ static uint32_t addAirExtra(Sema* sema, uint32_t value) { return idx; } +// --- Forward declarations --- +static TypeIndex semaTypeOf(Sema* sema, AirInstRef ref); + // --- ZIR instruction handlers --- // Ported from src/Sema.zig instruction handlers. @@ -326,6 +332,17 @@ static void zirDbgVar( ZirInstRef operand_ref = sema->code.inst_datas[inst].str_op.operand; AirInstRef operand = resolveInst(sema, operand_ref); + // Skip comptime-only values: types have no runtime representation. + // Ported from src/Sema.zig addDbgVar: comptimeOnlySema / + // hasRuntimeBitsSema checks. + TypeIndex val_ty = semaTypeOf(sema, operand); + if (val_ty == IP_INDEX_TYPE_TYPE + || val_ty == IP_INDEX_COMPTIME_INT_TYPE + || val_ty == IP_INDEX_COMPTIME_FLOAT_TYPE + || val_ty == IP_INDEX_ENUM_LITERAL_TYPE) { + return; + } + const char* name = (const char*)&sema->code.string_bytes[str_idx]; uint32_t name_nts = semaAppendAirString(sema, name); @@ -558,6 +575,12 @@ static AirInstRef semaCoerce( return ref; if (src_ty == IP_INDEX_COMPTIME_INT_TYPE) return coerceIntRef(sema, ref, target_ty); + // Comptime int→int coercion: re-intern with target type. + if (AIR_REF_IS_IP(ref) + && sema->ip->items[src_ty].tag == IP_KEY_INT_TYPE + && sema->ip->items[target_ty].tag == IP_KEY_INT_TYPE) { + return coerceIntRef(sema, ref, target_ty); + } // Runtime int→int coercion: emit intcast. if (AIR_REF_IS_INST(ref) && sema->ip->items[src_ty].tag == IP_KEY_INT_TYPE @@ -730,6 +753,37 @@ static AirInstRef zirByteSwap(Sema* sema, SemaBlock* block, uint32_t inst) { return blockAddInst(block, AIR_INST_BYTE_SWAP, data); } +// isComptimeInt: check if an AIR ref is a comptime integer value. +// Returns true and sets *value if the ref is a comptime int. +static bool isComptimeInt( + const Sema* sema, AirInstRef ref, int64_t* value) { + if (!AIR_REF_IS_IP(ref)) + return false; + InternPoolIndex ip_idx = AIR_REF_TO_IP(ref); + if (ip_idx >= sema->ip->items_len) + return false; + InternPoolKey key = sema->ip->items[ip_idx]; + if (key.tag != IP_KEY_INT) + return false; + if (key.data.int_val.is_negative) + *value = -(int64_t)key.data.int_val.value; + else + *value = (int64_t)key.data.int_val.value; + return true; +} + +// internComptimeInt: intern a comptime integer value with given type. +static AirInstRef internComptimeInt( + Sema* sema, TypeIndex ty, uint64_t value) { + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT; + key.data.int_val.ty = ty; + key.data.int_val.value = value; + key.data.int_val.is_negative = false; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); +} + // zirArithmetic: handle add/sub ZIR instructions. // Ported from src/Sema.zig zirArithmetic. static AirInstRef zirArithmetic( @@ -740,6 +794,40 @@ static AirInstRef zirArithmetic( ZirInstRef zir_rhs = sema->code.extra[payload_index + 1]; AirInstRef lhs = resolveInst(sema, zir_lhs); AirInstRef rhs = resolveInst(sema, zir_rhs); + + // Comptime folding: if both operands are comptime integers, + // compute the result at comptime. + int64_t lhs_val; + int64_t rhs_val; + if (isComptimeInt(sema, lhs, &lhs_val) + && isComptimeInt(sema, rhs, &rhs_val)) { + int64_t result; + TypeIndex lhs_ty = semaTypeOf(sema, lhs); + TypeIndex rhs_ty = semaTypeOf(sema, rhs); + TypeIndex result_ty = (lhs_ty == IP_INDEX_COMPTIME_INT_TYPE) + ? rhs_ty : lhs_ty; + if (result_ty == IP_INDEX_COMPTIME_INT_TYPE) + result_ty = IP_INDEX_COMPTIME_INT_TYPE; + switch (air_tag) { + case AIR_INST_ADD: + case AIR_INST_ADD_WRAP: + result = lhs_val + rhs_val; + break; + case AIR_INST_SUB: + case AIR_INST_SUB_WRAP: + result = lhs_val - rhs_val; + break; + case AIR_INST_MUL: + case AIR_INST_MUL_WRAP: + result = lhs_val * rhs_val; + break; + default: + goto emit_runtime; + } + return internComptimeInt(sema, result_ty, (uint64_t)result); + } + +emit_runtime:; TypeIndex peer_ty = resolvePeerType(sema, lhs, rhs); lhs = semaCoerce(sema, block, peer_ty, lhs); rhs = semaCoerce(sema, block, peer_ty, rhs); @@ -874,6 +962,12 @@ static void zirTypeofLog2IntType(Sema* sema, uint32_t inst) { ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand; AirInstRef operand = resolveInst(sema, operand_ref); TypeIndex operand_ty = semaTypeOf(sema, operand); + // Handle comptime_int: upstream returns comptime_int directly. + if (operand_ty == IP_INDEX_COMPTIME_INT_TYPE) { + instMapPut(&sema->inst_map, inst, + AIR_REF_FROM_IP(IP_INDEX_COMPTIME_INT_TYPE)); + return; + } assert(sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE); uint16_t bits = sema->ip->items[operand_ty].data.int_type.bits; // Compute ceil(log2(bits)): count bits needed to represent 0..bits-1. @@ -921,6 +1015,22 @@ static AirInstRef zirShl( ZirInstRef rhs_ref = sema->code.extra[payload_index + 1]; AirInstRef lhs = resolveInst(sema, lhs_ref); AirInstRef rhs = resolveInst(sema, rhs_ref); + + // Comptime folding for shift operations. + int64_t lhs_val; + int64_t rhs_val; + if (isComptimeInt(sema, lhs, &lhs_val) + && isComptimeInt(sema, rhs, &rhs_val)) { + TypeIndex lhs_ty = semaTypeOf(sema, lhs); + uint64_t result; + if (air_tag == AIR_INST_SHL) { + result = (uint64_t)lhs_val << (uint32_t)rhs_val; + } else { + result = (uint64_t)lhs_val >> (uint32_t)rhs_val; + } + return internComptimeInt(sema, lhs_ty, result); + } + AirInstData data; memset(&data, 0, sizeof(data)); data.bin_op.lhs = lhs; @@ -1486,11 +1596,21 @@ static AirInstRef zirCall(Sema* sema, SemaBlock* block, uint32_t inst, // Emit dbg_arg_inline for each param. if (!child_block.is_comptime) { - uint32_t param_payload - = sema->code.inst_datas[param_body[p]] - .pl_tok.payload_index; - uint32_t param_name_idx - = sema->code.extra[param_payload]; + uint32_t param_name_idx; + if (ptag == ZIR_INST_PARAM_ANYTYPE + || ptag == ZIR_INST_PARAM_ANYTYPE_COMPTIME) { + // str_tok: name is at str_tok.start. + param_name_idx + = sema->code.inst_datas[param_body[p]] + .str_tok.start; + } else { + // pl_tok: name is extra[payload_index + 0]. + uint32_t param_payload + = sema->code.inst_datas[param_body[p]] + .pl_tok.payload_index; + param_name_idx + = sema->code.extra[param_payload]; + } const char* param_name = (const char*)&sema->code .string_bytes[param_name_idx]; @@ -2093,10 +2213,11 @@ static AirInstRef zirFieldValComptime(Sema* sema, uint32_t inst) { && strcmp(field_name, "bits") == 0) { // Access .bits on a float_info result. // ct_val is the bits count. + // The .bits field has type u16 in std.builtin.Type.Float. InternPoolKey key; memset(&key, 0, sizeof(key)); key.tag = IP_KEY_INT; - key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; + key.data.int_val.ty = IP_INDEX_U16_TYPE; key.data.int_val.value = ct_val; key.data.int_val.is_negative = false; return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); @@ -2126,6 +2247,184 @@ static InternPoolIndex resolveUnsignedIntType( } } +// zirStructInitComptime: handle struct_init in comptime context. +// For @Type(.{.int = .{.signedness = .unsigned, .bits = N}}): +// - inner struct: extract signedness and bits, track as CT_TAG_INT_INFO +// - outer struct: extract field name (.int), track as CT_TAG_REIFY_INT +static AirInstRef zirStructInitComptime(Sema* sema, uint32_t inst) { + uint32_t payload_index + = sema->code.inst_datas[inst].pl_node.payload_index; + // StructInit payload: abs_node, abs_line, fields_len, then Items. + uint32_t fields_len = sema->code.extra[payload_index + 2]; + const uint32_t* items = &sema->code.extra[payload_index + 3]; + + // Check if this is the inner int struct (signedness + bits). + // Look at field names from the struct_init_field_type instructions. + uint32_t signedness = 0; + uint32_t bits_val = 0; + bool has_signedness = false; + bool has_bits = false; + const char* outer_field_name = NULL; + InternPoolIndex inner_ip = IP_INDEX_NONE; + + for (uint32_t f = 0; f < fields_len; f++) { + uint32_t field_type_inst = items[f * 2]; + ZirInstRef init_ref = items[f * 2 + 1]; + + // Get field name from struct_init_field_type instruction. + uint32_t ft_payload + = sema->code.inst_datas[field_type_inst].pl_node.payload_index; + uint32_t name_start = sema->code.extra[ft_payload + 1]; + const char* name + = (const char*)&sema->code.string_bytes[name_start]; + + AirInstRef init_air = resolveInst(sema, init_ref); + + if (strcmp(name, "signedness") == 0) { + has_signedness = true; + // The init should resolve to 0 (unsigned) or 1 (signed). + // It comes from decl_literal(.unsigned) or + // a comptime int. + if (AIR_REF_IS_IP(init_air)) { + InternPoolIndex ip_idx = AIR_REF_TO_IP(init_air); + InternPoolKey key_val = sema->ip->items[ip_idx]; + if (key_val.tag == IP_KEY_INT) { + signedness = (uint32_t)key_val.data.int_val.value; + } + } + } else if (strcmp(name, "bits") == 0) { + has_bits = true; + if (AIR_REF_IS_IP(init_air)) { + InternPoolIndex ip_idx = AIR_REF_TO_IP(init_air); + InternPoolKey key_val = sema->ip->items[ip_idx]; + if (key_val.tag == IP_KEY_INT) { + bits_val = (uint32_t)key_val.data.int_val.value; + } + } + } else if (strcmp(name, "int") == 0) { + outer_field_name = name; + if (AIR_REF_IS_IP(init_air)) { + inner_ip = AIR_REF_TO_IP(init_air); + } + } + } + + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT; + key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; + key.data.int_val.is_negative = false; + + if (has_signedness && has_bits) { + // Inner struct: .{.signedness = S, .bits = N} + key.data.int_val.value = 0x51F70000 + | ((uint64_t)signedness << 16) | bits_val; + InternPoolIndex marker = ipIntern(sema->ip, key); + ctTrack(sema, marker, CT_TAG_INT_INFO, + (signedness << 16) | bits_val); + return AIR_REF_FROM_IP(marker); + } + + if (outer_field_name != NULL + && strcmp(outer_field_name, "int") == 0) { + // Outer struct: .{.int = <inner>} + key.data.int_val.value = 0x52E10000 + inner_ip; + InternPoolIndex marker = ipIntern(sema->ip, key); + ctTrack(sema, marker, CT_TAG_REIFY_INT, inner_ip); + return AIR_REF_FROM_IP(marker); + } + + return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); +} + +// zirReifyComptime: handle @Type(...) in comptime context. +// Looks up the comptime-tracked argument to determine the type. +static AirInstRef zirReifyComptime(Sema* sema, uint32_t inst) { + uint16_t opcode = sema->code.inst_datas[inst].extended.opcode; + (void)opcode; + uint32_t operand_extra = sema->code.inst_datas[inst].extended.operand; + // Reify payload: node, operand_ref, src_line. + ZirInstRef operand_ref = sema->code.extra[operand_extra + 1]; + AirInstRef operand = resolveInst(sema, operand_ref); + + if (!AIR_REF_IS_IP(operand)) + return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + + InternPoolIndex op_ip = AIR_REF_TO_IP(operand); + uint32_t ct_val; + uint8_t ct_tag = ctLookup(sema, op_ip, &ct_val); + + if (ct_tag == CT_TAG_REIFY_INT) { + // The operand is .{.int = <inner>}. + // Look up the inner int_info. + uint32_t inner_val; + uint8_t inner_tag = ctLookup(sema, ct_val, &inner_val); + if (inner_tag == CT_TAG_INT_INFO) { + uint32_t s = (inner_val >> 16) & 0xFFFF; + uint32_t b = inner_val & 0xFFFF; + if (s == 0) { + return AIR_REF_FROM_IP( + resolveUnsignedIntType(sema->ip, b)); + } + // Signed int type. + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT_TYPE; + key.data.int_type.signedness = 1; + key.data.int_type.bits = (uint16_t)b; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); + } + } else if (ct_tag == CT_TAG_INT_INFO) { + // Direct int_info (no outer wrapping). + uint32_t s = (ct_val >> 16) & 0xFFFF; + uint32_t b = ct_val & 0xFFFF; + if (s == 0) { + return AIR_REF_FROM_IP( + resolveUnsignedIntType(sema->ip, b)); + } + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT_TYPE; + key.data.int_type.signedness = 1; + key.data.int_type.bits = (uint16_t)b; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); + } + + return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); +} + +// zirDeclLiteralComptime: handle decl_literal in comptime context. +// For enum literals like .unsigned, resolve to the enum value. +static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) { + uint32_t payload_index + = sema->code.inst_datas[inst].pl_node.payload_index; + // Field payload: lhs(Ref), field_name_start(u32). + uint32_t field_name_start = sema->code.extra[payload_index + 1]; + const char* field_name + = (const char*)&sema->code.string_bytes[field_name_start]; + + // For std.builtin.Signedness enum: unsigned=0, signed=1. + if (strcmp(field_name, "unsigned") == 0) { + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT; + key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; + key.data.int_val.value = 0; + key.data.int_val.is_negative = false; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); + } else if (strcmp(field_name, "signed") == 0) { + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_INT; + key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; + key.data.int_val.value = 1; + key.data.int_val.is_negative = false; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); + } + + return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); +} + // --- analyzeBodyInner --- // Ported from src/Sema.zig analyzeBodyInner. // Main dispatch loop: iterates over ZIR instructions in a body and @@ -2292,12 +2591,15 @@ static bool analyzeBodyInner( // extended: handle extended opcodes. case ZIR_INST_EXTENDED: { uint16_t opcode = sema->code.inst_datas[inst].extended.opcode; + AirInstRef air_ref; if (opcode == ZIR_EXT_STRUCT_DECL) { zirStructDecl(sema, block, inst); + air_ref = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + } else if (opcode == ZIR_EXT_REIFY) { + air_ref = zirReifyComptime(sema, inst); + } else { + air_ref = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); } - // Map the extended instruction to void; full type - // machinery is not yet implemented. - AirInstRef air_ref = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); instMapPut(&sema->inst_map, inst, air_ref); i++; continue; @@ -2608,17 +2910,150 @@ static bool analyzeBodyInner( i++; continue; - // @TypeOf(operand) — handled by default (void) for now. - // zirTypeof is used for cross-module comptime eval. + // @TypeOf(operand): resolve the type of the operand. + case ZIR_INST_TYPEOF: + instMapPut(&sema->inst_map, inst, zirTypeof(sema, inst)); + i++; + continue; - // @TypeOf builtin with block body — handled by default (void) - // for now. Cross-module comptime eval uses this inline. + // @TypeOf builtin with block body: analyze body, then typeof. + // Uses a child block and saves/restores AIR state. + case ZIR_INST_TYPEOF_BUILTIN: { + ZirInstData data = sema->code.inst_datas[inst]; + uint32_t payload_index = data.pl_node.payload_index; + uint32_t inner_body_len = sema->code.extra[payload_index]; + const uint32_t* inner_body + = &sema->code.extra[payload_index + 1]; + + SemaBlock ct_block; + semaBlockInit(&ct_block, sema, block); + ct_block.is_comptime = true; + ct_block.is_typeof = true; + ct_block.inlining = block->inlining; + + uint32_t saved_air_len = sema->air_inst_len; + uint32_t saved_extra_len = sema->air_extra_len; + + bool completed = analyzeBodyInner( + sema, &ct_block, inner_body, inner_body_len); + + sema->air_inst_len = saved_air_len; + sema->air_extra_len = saved_extra_len; + + AirInstRef result; + if (!completed) { + uint32_t break_inst = sema->comptime_break_inst; + ZirInstData break_data + = sema->code.inst_datas[break_inst]; + ZirInstRef operand = break_data.break_data.operand; + if (operand == ZIR_REF_NONE) { + result = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + } else { + AirInstRef resolved = resolveInst(sema, operand); + TypeIndex ty = semaTypeOf(sema, resolved); + result = AIR_REF_FROM_IP(ty); + } + } else { + result = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + } + semaBlockDeinit(&ct_block); + instMapPut(&sema->inst_map, inst, result); + i++; + continue; + } + + // block_comptime: like block_inline but with extra reason word. + // Creates a temporary child block and saves/restores AIR state + // so comptime-internal instructions are not counted. + case ZIR_INST_BLOCK_COMPTIME: { + ZirInstData data = sema->code.inst_datas[inst]; + uint32_t payload_index = data.pl_node.payload_index; + // Payload: reason (1 word), body_len (1 word), body... + uint32_t inner_body_len + = sema->code.extra[payload_index + 1]; + const uint32_t* inner_body + = &sema->code.extra[payload_index + 2]; - // @typeInfo(type) — handled by default (void) for now. - // zirTypeInfoComptime is used for cross-module comptime eval. + SemaBlock ct_block; + semaBlockInit(&ct_block, sema, block); + ct_block.is_comptime = true; + ct_block.inlining = block->inlining; - // field_val — field access: handled by default (void) for now. - // zirFieldValComptime is used for cross-module comptime eval. + // Save AIR state so comptime instructions are discarded. + uint32_t saved_air_len = sema->air_inst_len; + uint32_t saved_extra_len = sema->air_extra_len; + + bool completed = analyzeBodyInner( + sema, &ct_block, inner_body, inner_body_len); + + // Restore AIR state (discard comptime instructions). + sema->air_inst_len = saved_air_len; + sema->air_extra_len = saved_extra_len; + + if (!completed) { + uint32_t break_inst = sema->comptime_break_inst; + ZirInstData break_data + = sema->code.inst_datas[break_inst]; + ZirInstRef operand = break_data.break_data.operand; + AirInstRef result; + if (operand == ZIR_REF_NONE) { + result = AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + } else { + result = resolveInst(sema, operand); + } + instMapPut(&sema->inst_map, inst, result); + } + semaBlockDeinit(&ct_block); + i++; + continue; + } + + // @typeInfo(type): comptime type info extraction. + case ZIR_INST_TYPE_INFO: + instMapPut(&sema->inst_map, inst, + zirTypeInfoComptime(sema, inst)); + i++; + continue; + + // field_val: comptime field access on type_info results. + case ZIR_INST_FIELD_VAL: + instMapPut(&sema->inst_map, inst, + zirFieldValComptime(sema, inst)); + i++; + continue; + + // Validation-only struct init instructions: no-op. + case ZIR_INST_VALIDATE_STRUCT_INIT_TY: + case ZIR_INST_VALIDATE_STRUCT_INIT_RESULT_TY: + case ZIR_INST_VALIDATE_PTR_STRUCT_INIT: + case ZIR_INST_STRUCT_INIT_FIELD_TYPE: + case ZIR_INST_STRUCT_INIT_FIELD_PTR: + instMapPut(&sema->inst_map, inst, + AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE)); + i++; + continue; + + // struct_init: comptime struct initialization. + case ZIR_INST_STRUCT_INIT: + instMapPut(&sema->inst_map, inst, + zirStructInitComptime(sema, inst)); + i++; + continue; + + // decl_literal: resolve enum/decl literals at comptime. + case ZIR_INST_DECL_LITERAL: + case ZIR_INST_DECL_LITERAL_NO_COERCE: + instMapPut(&sema->inst_map, inst, + zirDeclLiteralComptime(sema, inst)); + i++; + continue; + + // str: string literal — map to void in comptime context. + case ZIR_INST_STR: + instMapPut(&sema->inst_map, inst, + AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE)); + i++; + continue; // For all other instructions, produce a void mapping and skip. // As handlers are implemented, they will replace this default. diff --git a/stage0/stages_test.zig b/stage0/stages_test.zig @@ -102,7 +102,7 @@ const corpus_files = .{ "../lib/std/crypto/codecs.zig", // 165 "../lib/std/os/uefi/tables/table_header.zig", // 214 "../lib/std/zig/llvm.zig", // 247 - //"../lib/compiler_rt/neghf2.zig", // 265 -- cross-module ZIR loading works; needs comptime eval (reify, struct_init) + "../lib/compiler_rt/neghf2.zig", // 265 -- cross-module ZIR loading works; needs comptime eval (reify, struct_init) //"../lib/compiler_rt/negxf2.zig", // 265 -- @export+func_fancy handled; body analysis incomplete //"../lib/compiler_rt/absvdi2.zig", // 311 -- @export+func_fancy handled; body analysis incomplete //"../lib/compiler_rt/absvsi2.zig", // 311 -- @export+func_fancy handled; body analysis incomplete