zig

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

commit 64e2ca5959ab1e6995ecd93c793ca01e1fb01d93 (tree)
parent 22f6b25a1adce13470d743a9f31e98d3ba53a9f0
Author: Motiejus <motiejus@jakstys.lt>
Date:   Thu, 26 Feb 2026 22:58:46 +0000

sema: return ptr_nav from comptime FIELD_PTR instead of raw type

In the comptime path of zirFieldPtr, return a ptr_nav (pointer to the
nav) instead of the raw resolved_type value. This matches the Zig
compiler's analyzeNavRef pattern where field pointer access on a type
produces a pointer to the declaration, not the type value itself.

The ptr_nav is created via ipIntern which deduplicates against any
existing ptr_nav created during init, avoiding duplicate entries.

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

Diffstat:
Mstage0/sema.c | 27++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -10115,19 +10115,32 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) { // look up the field in the type's namespace. This handles patterns // like @import("builtin").target where the import resolves to a // struct type and we need namespace member access. - // Only returns already-resolved nav values — does NOT trigger - // analyzeNavValC which would create IP entries out of order. + // Ported from Sema.zig fieldPtr → namespaceLookupRef → analyzeNavRef. + // Does NOT trigger resolution to avoid recursion — only handles + // already-resolved navs. if (AIR_REF_IS_IP(obj) && block->is_comptime) { InternPoolIndex obj_ip = AIR_REF_TO_IP(obj); InternPoolIndex obj_type = ipTypeOf(sema->ip, obj_ip); if (obj_type == IP_INDEX_TYPE_TYPE) { uint32_t ns = findNamespaceForType(obj_ip); if (ns != UINT32_MAX) { - uint32_t nav = findNavInNamespace(ns, field_name); - if (nav != UINT32_MAX) { - const Nav* n = ipGetNav(nav); - if (n->resolved_type != IP_INDEX_NONE) - return AIR_REF_FROM_IP(n->resolved_type); + uint32_t nav_idx = findNavInNamespace(ns, field_name); + if (nav_idx != UINT32_MAX) { + const Nav* n = ipGetNav(nav_idx); + if (n->resolved_type != IP_INDEX_NONE) { + // Check if a ptr_nav already exists for this + // nav (created during init). If so, return it + // to match Zig's analyzeNavRef pattern. + InternPoolIndex val_ty = n->resolved_type; + InternPoolIndex ptr_ty = internPtrConst(val_ty); + InternPoolKey pk; + memset(&pk, 0, sizeof(pk)); + pk.tag = IP_KEY_PTR_NAV; + pk.data.ptr_nav.ty = ptr_ty; + pk.data.ptr_nav.nav = nav_idx; + InternPoolIndex pn = ipIntern(sema->ip, pk); + return AIR_REF_FROM_IP(pn); + } } } }