zig

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

commit 7c7f65625a2ec012cd42a963329098982a0c9c76 (tree)
parent 7b0bb54b5c8af3bcfca57432e43fd78cae36c703
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sat, 28 Feb 2026 16:56:05 +0000

sema: replace resolveBuiltinModuleChain with demand-driven import resolution

Replace the manual std → std/builtin.zig → CG builtin module chain
construction with targeted ensureNavValUpToDate calls that trigger the
same chain through normal import resolution:

  1. Resolve start.zig's "builtin" import via ensureNavValUpToDate
  2. Resolve std.zig's "builtin" import → loads std/builtin.zig
  3. resolveModuleDeclImports on std/builtin.zig → resolves its "std"
     and "builtin" imports, the latter creating CG builtin on demand

Add ensureCgBuiltinModule() that creates the virtual CG builtin module
on first @import("builtin") encounter. Add @import("root") handling
ported from PerThread.zig doImport.

Remove resolveBuiltinModuleChain (now dead code) and its hardcoded
path matching ("/std/std.zig") and IP index comments ($137-$141).

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

Diffstat:
Mstage0/sema.c | 194++++++++++++++++++++++++++++++++-----------------------------------------------
1 file changed, 78 insertions(+), 116 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -2301,7 +2301,35 @@ static InternPoolIndex createModuleStructType(void) { return ipIntern(s_module_ip, key); } -// (ensureModuleStructType removed — replaced by ensureFileAnalyzedC) +// Forward declaration for createNamespace (defined below). +static uint32_t createNamespace(InternPoolIndex owner_type, uint32_t file_idx); + +// ensureCgBuiltinModule: create the compiler-generated builtin module +// on demand, the first time @import("builtin") is encountered. +// Ported from Compilation.zig updateBuiltinModule: creates a virtual +// module with no ZIR, storing navs for is_test, object_format, etc. +// Returns the CG builtin struct type, or IP_INDEX_NONE on failure. +static InternPoolIndex ensureCgBuiltinModule(void) { + // Already created — return cached type. + if (s_cg_builtin_ns_idx != UINT32_MAX) + return s_namespaces[s_cg_builtin_ns_idx].owner_type; + + if (!s_module_ip || s_num_loaded_modules >= MAX_LOADED_MODULES) + return IP_INDEX_NONE; + + InternPoolIndex cg_struct = createModuleStructType(); + uint32_t cg_file_idx = s_num_loaded_modules++; + LoadedModule* cg_mod = &s_loaded_modules[cg_file_idx]; + memset(cg_mod, 0, sizeof(*cg_mod)); + snprintf(cg_mod->path, sizeof(cg_mod->path), "<builtin>"); + cg_mod->analyzed = true; + s_file_root_type[cg_file_idx] = cg_struct; + uint32_t cg_ns_idx = createNamespace(cg_struct, cg_file_idx); + s_file_namespace[cg_file_idx] = cg_ns_idx; + s_cg_builtin_ns_idx = cg_ns_idx; + + return cg_struct; +} // --- Namespace creation --- // Ported from Zcu.Namespace. @@ -2570,107 +2598,7 @@ static uint32_t findNavInNamespace(uint32_t ns_idx, const char* name) { // Forward declaration for resolveModuleDeclImports (used below). static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth); -// --- resolveBuiltinModuleChain --- -// Ported from PerThread.zig analyzeMemoizedState (module loading part). -// After the root module and its direct imports are loaded, this function -// continues loading the module chain needed by @export resolution: -// std → std/builtin.zig → compiler-generated builtin → ... -// Creates type_struct and ptr_nav entries in the same order as the -// Zig compiler's demand-driven analysis. - -static void resolveBuiltinModuleChain(uint32_t start_file_idx) { - if (!s_module_ip || !s_global_module_root) - return; - - // Find std module among loaded modules. - uint32_t std_file_idx = UINT32_MAX; - for (uint32_t i = 0; i < s_num_loaded_modules; i++) { - const char* p = s_loaded_modules[i].path; - size_t plen = strlen(p); - // Match paths ending with "/std/std.zig" or "/std.zig" - if (plen >= 12 && strcmp(p + plen - 12, "/std/std.zig") == 0) { - std_file_idx = i; - break; - } - } - if (std_file_idx == UINT32_MAX) - return; - s_std_file_idx = std_file_idx; - - // Find `builtin` Nav in std's namespace. - // In std.zig: `pub const builtin = @import("builtin.zig");` - uint32_t std_ns_idx = s_file_namespace[std_file_idx]; - uint32_t builtin_nav = findNavInNamespace(std_ns_idx, "builtin"); - if (builtin_nav == UINT32_MAX) - return; - - // Load std/builtin.zig → creates type_struct entry ($137). - char builtin_path[1024]; - snprintf(builtin_path, sizeof(builtin_path), "%s/builtin.zig", - s_loaded_modules[std_file_idx].source_dir); - uint32_t builtin_file_idx = ensureFileAnalyzedC(builtin_path); - if (builtin_file_idx == UINT32_MAX) - return; - s_builtin_file_idx = builtin_file_idx; - - InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE); - - // $138: Create ptr_nav for `builtin` in start.zig's namespace. - // start.zig has `const builtin = @import("builtin")` which is the - // compiler-generated builtin. The Zig compiler evaluates this during - // start.zig's comptime block processing. - if (start_file_idx != UINT32_MAX) { - uint32_t start_ns_idx = s_file_namespace[start_file_idx]; - uint32_t start_builtin_nav - = findNavInNamespace(start_ns_idx, "builtin"); - if (start_builtin_nav != UINT32_MAX) - (void)internNavPtr(ptr_type, start_builtin_nav); - } - - // $139: Create ptr_nav for `std` in std/builtin.zig's namespace. - uint32_t builtin_ns_idx = s_file_namespace[builtin_file_idx]; - uint32_t std_in_builtin_nav = findNavInNamespace(builtin_ns_idx, "std"); - if (std_in_builtin_nav != UINT32_MAX) { - Nav* sNav = ipGetNav(std_in_builtin_nav); - sNav->resolved_type = s_file_root_type[std_file_idx]; - (void)internNavPtr(ptr_type, std_in_builtin_nav); - } - - // $140: Create CG builtin struct type. - // std/builtin.zig imports @import("builtin") — the compiler-generated - // builtin module. Create a type_struct for it even though we don't have - // its source. The Zig compiler creates this struct in semaFile. - uint32_t cg_builtin_nav_local - = findNavInNamespace(builtin_ns_idx, "builtin"); - if (cg_builtin_nav_local != UINT32_MAX) { - InternPoolIndex cg_struct = createModuleStructType(); - - if (s_num_loaded_modules < MAX_LOADED_MODULES) { - uint32_t cg_file_idx = s_num_loaded_modules++; - LoadedModule* cg_mod = &s_loaded_modules[cg_file_idx]; - memset(cg_mod, 0, sizeof(*cg_mod)); - snprintf(cg_mod->path, sizeof(cg_mod->path), "<builtin>"); - cg_mod->analyzed = true; - s_file_root_type[cg_file_idx] = cg_struct; - uint32_t cg_ns_idx = createNamespace(cg_struct, cg_file_idx); - s_file_namespace[cg_file_idx] = cg_ns_idx; - s_cg_builtin_ns_idx = cg_ns_idx; - - Nav* cgNav = ipGetNav(cg_builtin_nav_local); - cgNav->resolved_type = cg_struct; - // Save nav for deferred ptr_nav creation at $488. - s_cg_builtin_nav = cg_builtin_nav_local; - } - } - - // $141: Create ptr_nav for `builtin` in std's namespace. - // Deferred from earlier to match Zig compiler entry order. - Nav* bNav = ipGetNav(builtin_nav); - bNav->resolved_type = s_file_root_type[builtin_file_idx]; - (void)internNavPtr(ptr_type, builtin_nav); -} - -// Forward declarations for functions used by resolveNamedImport. +// Forward declarations for import resolution functions. static const char* findDeclImportPathFromZir( const Zir* zir, uint32_t decl_inst); static bool resolveImportPath(const char* source_dir, const char* import_path, @@ -4833,11 +4761,10 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) { = (const char*)&zir->string_bytes[path_idx]; // @import("builtin") — resolve to the compiler-generated - // builtin module's root struct type. + // builtin module (created on demand). if (strcmp(import_path, "builtin") == 0) { - if (s_cg_builtin_ns_idx != UINT32_MAX) { - InternPoolIndex cg_struct - = s_namespaces[s_cg_builtin_ns_idx].owner_type; + InternPoolIndex cg_struct = ensureCgBuiltinModule(); + if (cg_struct != IP_INDEX_NONE) { Nav* wnav = ipGetNav(nav_idx); wnav->resolved_type = cg_struct; return cg_struct; @@ -11412,12 +11339,12 @@ static bool analyzeBodyInner( = findDeclImportPath(sema, decl_name_idx); if (import_path) { - if (strcmp(import_path, "builtin") == 0 - && s_cg_builtin_ns_idx != UINT32_MAX) { + if (strcmp(import_path, "builtin") == 0) { // @import("builtin") — resolve to the CG - // builtin module's root struct type. - resolved - = s_namespaces[s_cg_builtin_ns_idx].owner_type; + // builtin module (created on demand). + InternPoolIndex cg = ensureCgBuiltinModule(); + if (cg != IP_INDEX_NONE) + resolved = cg; } else if (strcmp(import_path, "root") == 0 && s_root_file_idx != UINT32_MAX) { // @import("root") — the user's root module. @@ -11512,9 +11439,10 @@ static bool analyzeBodyInner( = (const char*)&sema->code.string_bytes[path_idx]; InternPoolIndex result = IP_INDEX_VOID_VALUE; - if (strcmp(import_path, "builtin") == 0 - && s_cg_builtin_ns_idx != UINT32_MAX) { - result = s_namespaces[s_cg_builtin_ns_idx].owner_type; + if (strcmp(import_path, "builtin") == 0) { + InternPoolIndex cg = ensureCgBuiltinModule(); + if (cg != IP_INDEX_NONE) + result = cg; } else if (strcmp(import_path, "root") == 0 && s_root_file_idx != UINT32_MAX) { // @import("root") → the user's root module. @@ -12238,8 +12166,42 @@ SemaFuncAirList semaAnalyze(Sema* sema) { } } - // Load std/builtin.zig chain ($137+). - resolveBuiltinModuleChain(start_file_idx); + // Load the builtin module chain by resolving specific + // import declarations, matching the upstream's memoized + // state analysis sequence. + // Ported from PerThread.zig analyzeMemoizedState. + if (std_file_idx != UINT32_MAX) { + s_std_file_idx = std_file_idx; + uint32_t std_ns_idx2 = s_file_namespace[std_file_idx]; + + // Resolve start.zig's "builtin" import ($138). + if (start_file_idx != UINT32_MAX) { + uint32_t start_ns = s_file_namespace[start_file_idx]; + uint32_t sbn = findNavInNamespace(start_ns, "builtin"); + if (sbn != UINT32_MAX) + (void)ensureNavValUpToDate(sbn); + } + + // Resolve std.zig's "builtin" import → loads + // std/builtin.zig ($137), creates ptr_nav ($141). + uint32_t builtin_nav + = findNavInNamespace(std_ns_idx2, "builtin"); + if (builtin_nav != UINT32_MAX) { + InternPoolIndex bval = ensureNavValUpToDate(builtin_nav); + if (bval != IP_INDEX_NONE) { + for (uint32_t fi = 0; fi < s_num_loaded_modules; + fi++) { + if (s_file_root_type[fi] == bval) { + s_builtin_file_idx = fi; + // Resolve std/builtin.zig's imports + // ($139 std, $140 CG builtin). + resolveModuleDeclImports(fi, 1); + break; + } + } + } + } + } } else { // No module root — root module is file_idx=0. if (s_num_loaded_modules == 0) {