zig

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

commit e3af422003046575754ce886fb0748cf307ff19f (tree)
parent 7af3e9e6b79a95a95c282344be02e540fb571d07
Author: Motiejus <motiejus@jakstys.lt>
Date:   Fri, 27 Feb 2026 14:56:34 +0000

sema: fix analyzeNavValC default, add type body fallback

Two changes to improve IP entry matching for declarations whose value
bodies can't be fully evaluated:

1. analyzeNavValC: change default result from IP_INDEX_VOID_VALUE to
   IP_INDEX_NONE. Previously, unevaluable declarations (e.g. struct
   literals like `const lime1: CpuModel = .{...}`) got resolved_type
   set to void, causing spurious *const void entries.

2. analyzeNavValC: when value body evaluation fails, extract and resolve
   the TYPE annotation body from ZIR. For `const x: T = <unevaluable>`,
   this sets resolved_type to T so resolveNavRef can create a correct
   ptr_nav(*const T) instead of no entry at all.

3. getTypeBodyFromZir: new helper to extract the type body from a
   ZIR_INST_DECLARATION, complementing getValueBodyFromZir.

IP gap for neghf2 reduced: first mismatch moved from [692] to [699].

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

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

diff --git a/stage0/sema.c b/stage0/sema.c @@ -2772,6 +2772,8 @@ static void resolveRootInStartModule( // Forward declaration for getValueBodyFromZir (defined later at ~line 7032). static void getValueBodyFromZir(const Zir* zir, uint32_t decl_inst, const uint32_t** body_out, uint32_t* body_len_out); +static void getTypeBodyFromZir(const Zir* zir, uint32_t decl_inst, + const uint32_t** body_out, uint32_t* body_len_out); // --- resolveZirRefValue --- // Resolve a ZIR ref from an arbitrary module's ZIR to an IP index. @@ -4844,7 +4846,7 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) { bool completed = analyzeBodyInner(&mini_sema, &ct_block, value_body, value_body_len); - AirInstRef result = AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); + AirInstRef result = AIR_REF_FROM_IP(IP_INDEX_NONE); if (!completed) { uint32_t break_inst = mini_sema.comptime_break_inst; ZirInstData break_data = mini_sema.code.inst_datas[break_inst]; @@ -4857,8 +4859,30 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) { semaBlockDeinit(&ct_block); semaDeinit(&mini_sema); - if (!AIR_REF_IS_IP(result)) + if (!AIR_REF_IS_IP(result) || AIR_REF_TO_IP(result) == IP_INDEX_NONE) { + // Value body evaluation failed. Try to resolve the TYPE annotation + // so that resolveNavRef can create a ptr_nav with the correct type. + // For `const lime1: CpuModel = .{...}`, the type body resolves to + // CpuModel even though the struct literal can't be evaluated. + const uint32_t* type_body = NULL; + uint32_t type_body_len = 0; + getTypeBodyFromZir(zir, nav->zir_index, &type_body, &type_body_len); + if (type_body && type_body_len > 0) { + uint32_t last_inst = type_body[type_body_len - 1]; + if (last_inst < zir->inst_len + && zir->inst_tags[last_inst] == ZIR_INST_BREAK_INLINE) { + ZirInstRef op = zir->inst_datas[last_inst].break_data.operand; + InternPoolIndex type_result + = resolveZirTypeRef(zir, op, ns_idx, file_idx); + if (type_result != IP_INDEX_NONE) { + nav = ipGetNav(nav_idx); + nav->resolved_type = type_result; + return type_result; + } + } + } return IP_INDEX_NONE; + } InternPoolIndex result_ip = AIR_REF_TO_IP(result); InternPoolIndex result_type = ipTypeOf(s_module_ip, result_ip); @@ -10696,6 +10720,38 @@ static void getValueBodyFromZir(const Zir* zir, uint32_t decl_inst, *body_out = &zir->extra[di]; } +// getTypeBodyFromZir: extract type body from a ZIR_INST_DECLARATION. +// Similar to getValueBodyFromZir but returns the type annotation body +// instead of the value body. +static void getTypeBodyFromZir(const Zir* zir, uint32_t decl_inst, + const uint32_t** body_out, uint32_t* body_len_out) { + if (zir->inst_tags[decl_inst] != ZIR_INST_DECLARATION) { + *body_out = NULL; + *body_len_out = 0; + return; + } + uint32_t payload = zir->inst_datas[decl_inst].declaration.payload_index; + uint32_t flags_1 = zir->extra[payload + 5]; + uint32_t id = (flags_1 >> 27) & 0x1F; + uint32_t di = payload + 6; + if (declIdHasName(id)) + di++; + if (declIdHasLibName(id)) + di++; + uint32_t type_body_len = 0; + if (declIdHasTypeBody(id)) { + type_body_len = zir->extra[di]; + di++; + } + if (declIdHasSpecialBodies(id)) + di += 3; // align, linksection, addrspace lengths + if (declIdHasValueBody(id)) + di++; // value_body_len + // di now points to start of body data; type body is first + *body_len_out = type_body_len; + *body_out = (type_body_len > 0) ? &zir->extra[di] : NULL; +} + // evalCrossModuleDeclValue: evaluate a cross-module declaration's value body // using a temporary mini-sema. Returns the comptime result (e.g. BOOL_TRUE // or BOOL_FALSE), or VOID if the value cannot be resolved.