zig

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

commit 7b0bb54b5c8af3bcfca57432e43fd78cae36c703 (tree)
parent 248370697e0778777dcb24c009f1b79e76dde442
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sat, 28 Feb 2026 16:41:57 +0000

sema: replace resolveRootInStartModule with start.zig comptime eval

Evaluate start.zig's comptime blocks via analyzeComptimeUnit instead
of calling resolveRootInStartModule. The comptime block `_ = root;`
resolves @import("root") to the root module, creating the ptr_nav
entry as a side effect of DECL_VAL import resolution.

Add @import("root") handling in ZIR_INST_IMPORT and DECL_VAL handlers,
ported from PerThread.zig doImport "root" case. The root module's
file_idx is stored in s_root_file_idx, set during semaAnalyze.

Remove resolveRootInStartModule (now dead code).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 68+++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -2679,30 +2679,6 @@ static bool resolveImportPath(const char* source_dir, const char* import_path, // Forward declaration (defined later). static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx); -// --- resolveRootInStartModule --- -// After loading the root module, create a ptr_nav entry for the "root" -// Nav in start.zig's namespace. This matches the Zig compiler's -// evaluation of start.zig's `_ = root;` comptime block. -static void resolveRootInStartModule( - uint32_t start_file_idx, uint32_t root_file_idx) { - if (start_file_idx == UINT32_MAX || root_file_idx == UINT32_MAX) - return; - - uint32_t start_ns_idx = s_file_namespace[start_file_idx]; - uint32_t root_nav = findNavInNamespace(start_ns_idx, "root"); - if (root_nav == UINT32_MAX) - return; - - InternPoolIndex root_struct = s_file_root_type[root_file_idx]; - if (root_struct == 0 && root_file_idx > 0) - return; - - InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE); - Nav* nav = ipGetNav(root_nav); - nav->resolved_type = root_struct; - (void)internNavPtr(ptr_type, root_nav); -} - // 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); @@ -11439,13 +11415,23 @@ static bool analyzeBodyInner( if (strcmp(import_path, "builtin") == 0 && s_cg_builtin_ns_idx != UINT32_MAX) { // @import("builtin") — resolve to the CG - // builtin module's root struct type, like any - // other import. Field access will find navs - // through the struct's namespace, and - // ensureNavValUpToDate handles CG builtin navs - // via resolveCgBuiltinField. + // builtin module's root struct type. resolved = s_namespaces[s_cg_builtin_ns_idx].owner_type; + } else if (strcmp(import_path, "root") == 0 + && s_root_file_idx != UINT32_MAX) { + // @import("root") — the user's root module. + // Ported from PerThread.zig doImport "root". + resolved = s_file_root_type[s_root_file_idx]; + if (s_in_main_analysis) { + uint32_t nav_idx2 = findNavInNamespace( + s_file_namespace[sema->file_idx], decl_name); + if (nav_idx2 != UINT32_MAX) { + InternPoolIndex pt + = internPtrConst(IP_INDEX_TYPE_TYPE); + (void)internNavPtr(pt, nav_idx2); + } + } } else if (sema->source_dir) { char import_full[1024]; if (resolveImportPath(sema->source_dir, import_path, @@ -11501,7 +11487,8 @@ static bool analyzeBodyInner( // Non-comptime: just load import side effects. const char* import_path = findDeclImportPath(sema, decl_name_idx); - if (import_path && strcmp(import_path, "builtin") != 0) { + if (import_path && strcmp(import_path, "builtin") != 0 + && strcmp(import_path, "root") != 0) { char import_full[1024]; if (resolveImportPath(sema->source_dir, import_path, import_full, sizeof(import_full))) { @@ -11528,6 +11515,11 @@ static bool analyzeBodyInner( if (strcmp(import_path, "builtin") == 0 && s_cg_builtin_ns_idx != UINT32_MAX) { result = s_namespaces[s_cg_builtin_ns_idx].owner_type; + } else if (strcmp(import_path, "root") == 0 + && s_root_file_idx != UINT32_MAX) { + // @import("root") → the user's root module. + // Ported from PerThread.zig doImport "root" case. + result = s_file_root_type[s_root_file_idx]; } else if (sema->source_dir) { char import_full[1024]; if (resolveImportPath(sema->source_dir, import_path, @@ -12232,9 +12224,19 @@ SemaFuncAirList semaAnalyze(Sema* sema) { sema->file_idx = root_file_idx; (void)createFileRootStructC(root_file_idx, &sema->code); - // Create ptr_nav for "root" in start.zig ($136), - // matching start.zig's comptime { _ = root; }. - resolveRootInStartModule(start_file_idx, root_file_idx); + // Evaluate start.zig's comptime blocks. The first block + // contains `_ = root;` which resolves @import("root") to + // the root module, creating ptr_nav ($136). + // Ported from upstream: start.zig comptime evaluated after + // root module is registered so @import("root") resolves. + if (start_file_idx != UINT32_MAX) { + uint32_t start_ns = s_file_namespace[start_file_idx]; + const SemaNamespace* sns = &s_namespaces[start_ns]; + for (uint32_t ci = 0; ci < sns->comptime_decl_count; ci++) { + analyzeComptimeUnit( + start_file_idx, sns->comptime_decls[ci]); + } + } // Load std/builtin.zig chain ($137+). resolveBuiltinModuleChain(start_file_idx);