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:
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);
+ }
}
}
}