diff --git a/stage0/sema.c b/stage0/sema.c index 5c27297f50..a3eb27e8a7 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -4954,6 +4954,10 @@ void resolveTypeFullyC(Sema* sema, InternPoolIndex ip_idx) { case IP_KEY_ARRAY_TYPE: resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.array_type.child); break; + case IP_KEY_VECTOR_TYPE: + resolveTypeFullyC( + sema, sema->ip->items[ip_idx].data.vector_type.child); + break; case IP_KEY_SLICE: // Slice wraps a pointer type; resolve the pointer's child. resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.slice); @@ -11437,6 +11441,30 @@ static void zirExport(Sema* sema, uint32_t inst) { sema->exported_decl_names[sema->num_exported_decl_names++] = name_idx; } + // Fully resolve the exported declaration, matching Zig's + // analyzeExport → ensureNavResolved(.fully) (Sema.zig:6261). + // This creates func_type, func_decl, CC.c entries, etc. at the + // right IP position (during @export processing, not later during + // function body analysis). + const char* name + = (const char*)(sema->code.string_bytes + name_idx); + uint32_t root_ns = sema->zcu->file_namespaces[sema->file_idx]; + uint32_t nav = findNavInNamespace(sema, root_ns, name); + if (nav != UINT32_MAX) { + InternPoolIndex val = ensureNavValUpToDate(sema, nav); + // Fully resolve the function type, matching Zig's + // ensureNavResolved(.fully) which calls resolveFully + // on the function's type after creating it. + if (val != IP_INDEX_NONE) { + if (val < sema->ip->items_len + && sema->ip->items[val].tag == IP_KEY_FUNC) { + resolveTypeFullyC(sema, + sema->ip->items[val].data.func_decl.ty); + } else { + resolveTypeFullyC(sema, val); + } + } + } } } instMapPut(&sema->inst_map, inst, AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE)); diff --git a/stage0/zcu_per_thread.c b/stage0/zcu_per_thread.c index dc439e8aae..526704f98d 100644 --- a/stage0/zcu_per_thread.c +++ b/stage0/zcu_per_thread.c @@ -889,6 +889,16 @@ InternPoolIndex ensureNavValUpToDate(Sema* sema, uint32_t nav_idx) { break; setNavResolvedType(sema, nav_idx, struct_type); + // Create ptr_type + ptr_nav for the import nav during main + // analysis, matching Zig's analyzeNavRefInner which creates + // a compile-time pointer to every resolved nav. Only during + // main analysis (shard simulation active) — preamble creates + // these in a separate shard in Zig. + if (sema->ip->skip_dedup_start < sema->ip->skip_dedup_end) { + InternPoolIndex ptr_type + = internPtrConst(sema, IP_INDEX_TYPE_TYPE); + (void)internNavPtr(sema, ptr_type, nav_idx); + } return struct_type; } } @@ -942,7 +952,8 @@ InternPoolIndex internTypedInt(Sema* sema, InternPoolIndex ty, uint64_t val) { key.data.int_val.ty = ty; key.data.int_val.value_lo = val; key.data.int_val.is_negative = false; - return ipIntern(sema->ip, key); + InternPoolIndex result = ipIntern(sema->ip, key); + return result; } InternPoolIndex internFuncType(Sema* sema, InternPoolIndex return_type, @@ -1373,6 +1384,16 @@ void ensureFullMemoizedStateC(Sema* sema) { if (val == IP_INDEX_NONE) continue; + // Create ptr_type + ptr_nav for each builtin, matching Zig's + // analyzeMemoizedState which calls analyzeNavVal → analyzeNavRefInner + // (Sema.zig:37553 → 31279). This creates a pointer reference to + // the nav's value as a side effect of accessing it. + { + InternPoolIndex vt = ipTypeOf(sema->ip, val); + InternPoolIndex pt = internPtrConst(sema, vt); + (void)internNavPtr(sema, pt, nav); + } + sema->zcu->builtin_decl_values[i] = val; // Immediately resolveFully for type builtins, matching Zig's