commit e12b15769e96a0eed559c3bc791eb18c5dd0b30e (tree)
parent 4acf0de240f942f8955f270ece87613d491e65e2
Author: Motiejus <motiejus@jakstys.lt>
Date: Sat, 28 Feb 2026 19:24:47 +0000
sema: consolidate import resolution into doImport
Port doImport from PerThread.zig (lines 1967-2013). Centralizes
handling of special module names ("builtin", "root", "std") and
regular file paths into one function. Replaces scattered strcmp
dispatch in ZIR_INST_IMPORT, DECL_VAL, ensureNavValUpToDate, and
resolveModuleDeclImports with calls to doImport.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
| M | stage0/sema.c | | | 152 | ++++++++++++++++++++++++++++++++----------------------------------------------- |
1 file changed, 62 insertions(+), 90 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -2595,8 +2595,9 @@ static uint32_t findNavInNamespace(uint32_t ns_idx, const char* name) {
return UINT32_MAX;
}
-// Forward declaration for resolveModuleDeclImports (used below).
+// Forward declarations.
static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth);
+static uint32_t doImport(const char* source_dir, const char* import_string);
// Forward declarations for import resolution functions.
static const char* findDeclImportPathFromZir(
@@ -4760,23 +4761,10 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
const char* import_path
= (const char*)&zir->string_bytes[path_idx];
- // @import("builtin") — resolve to the compiler-generated
- // builtin module (created on demand).
- if (strcmp(import_path, "builtin") == 0) {
- InternPoolIndex cg_struct = ensureCgBuiltinModule();
- if (cg_struct != IP_INDEX_NONE) {
- Nav* wnav = ipGetNav(nav_idx);
- wnav->resolved_type = cg_struct;
- return cg_struct;
- }
- break;
- }
-
- char import_full[1024];
- if (!resolveImportPath(s_loaded_modules[file_idx].source_dir,
- import_path, import_full, sizeof(import_full)))
- break;
- uint32_t import_file_idx = ensureFileAnalyzedC(import_full);
+ // Resolve via doImport (handles "builtin", "root",
+ // "std", and file paths).
+ uint32_t import_file_idx
+ = doImport(s_loaded_modules[file_idx].source_dir, import_path);
if (import_file_idx == UINT32_MAX)
break;
@@ -5112,18 +5100,8 @@ static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth) {
if (!import_path)
continue;
- // Skip builtin imports.
- if (strcmp(import_path, "builtin") == 0)
- continue;
-
- // Resolve import path.
- char import_full[1024];
- if (!resolveImportPath(mod->source_dir, import_path, import_full,
- sizeof(import_full)))
- continue;
-
- // Load and analyze the imported file → type_struct.
- uint32_t import_file_idx = ensureFileAnalyzedC(import_full);
+ // Resolve via doImport (handles all special names).
+ uint32_t import_file_idx = doImport(mod->source_dir, import_path);
if (import_file_idx == UINT32_MAX)
continue;
InternPoolIndex struct_type = s_file_root_type[import_file_idx];
@@ -5189,6 +5167,45 @@ static void analyzeComptimeUnit(uint32_t file_idx, uint32_t comptime_decl) {
semaDeinit(&ct_sema);
}
+// --- doImport ---
+// Ported from src/Zcu/PerThread.zig doImport (lines 1967-2013).
+// Resolves an import string to a file index. Handles special module
+// names ("builtin", "root", "std") and regular file paths.
+// Returns file_idx, or UINT32_MAX if the import cannot be resolved.
+static uint32_t doImport(const char* source_dir, const char* import_string) {
+ // Special module names — ported from PerThread.zig doImport
+ // lines 1982-1990.
+ if (strcmp(import_string, "builtin") == 0) {
+ // @import("builtin") → compiler-generated builtin module.
+ InternPoolIndex cg = ensureCgBuiltinModule();
+ if (cg == IP_INDEX_NONE)
+ return UINT32_MAX;
+ // Find the CG builtin's file_idx.
+ for (uint32_t fi = 0; fi < s_num_loaded_modules; fi++) {
+ if (s_file_root_type[fi] == cg)
+ return fi;
+ }
+ return UINT32_MAX;
+ }
+ if (strcmp(import_string, "root") == 0) {
+ // @import("root") → user's root module.
+ return s_root_file_idx;
+ }
+ if (strcmp(import_string, "std") == 0) {
+ // @import("std") → standard library.
+ return s_std_file_idx;
+ }
+
+ // Regular file import — resolve path and load.
+ if (!source_dir)
+ return UINT32_MAX;
+ char import_full[1024];
+ if (!resolveImportPath(
+ source_dir, import_string, import_full, sizeof(import_full)))
+ return UINT32_MAX;
+ return ensureFileAnalyzedC(import_full);
+}
+
// --- ensureFileAnalyzedC ---
// Ported from src/Zcu/PerThread.zig ensureFileAnalyzed.
// Loads, parses, and analyzes an imported file. Creates struct type,
@@ -11250,18 +11267,15 @@ static bool analyzeBodyInner(
= findDeclImportPath(sema, decl_name_idx);
if (import_path) {
- if (strcmp(import_path, "builtin") == 0) {
- // @import("builtin") — resolve to the CG
- // 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.
- // Ported from PerThread.zig doImport "root".
- resolved = s_file_root_type[s_root_file_idx];
- if (s_in_main_analysis) {
+ // Resolve via doImport (handles "builtin",
+ // "root", "std", and file paths).
+ uint32_t fid = doImport(sema->source_dir, import_path);
+ if (fid != UINT32_MAX) {
+ resolved = s_file_root_type[fid];
+ // Create ptr_nav for the import nav,
+ // matching Zig's analyzeNavRefInner.
+ if (s_in_main_analysis
+ && sema->file_idx != UINT32_MAX) {
uint32_t nav_idx2 = findNavInNamespace(
s_file_namespace[sema->file_idx], decl_name);
if (nav_idx2 != UINT32_MAX) {
@@ -11270,27 +11284,6 @@ static bool analyzeBodyInner(
(void)internNavPtr(pt, nav_idx2);
}
}
- } else if (sema->source_dir) {
- char import_full[1024];
- if (resolveImportPath(sema->source_dir, import_path,
- import_full, sizeof(import_full))) {
- uint32_t fid = ensureFileAnalyzedC(import_full);
- if (fid != UINT32_MAX) {
- resolved = s_file_root_type[fid];
- // Create ptr_nav for the import nav,
- // matching Zig's analyzeNavRefInner.
- 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 {
// Not an import — look up by name in the
@@ -11325,13 +11318,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
- && strcmp(import_path, "root") != 0) {
- char import_full[1024];
- if (resolveImportPath(sema->source_dir, import_path,
- import_full, sizeof(import_full))) {
- (void)ensureFileAnalyzedC(import_full);
- }
+ if (import_path) {
+ (void)doImport(sema->source_dir, import_path);
}
}
@@ -11342,32 +11330,16 @@ static bool analyzeBodyInner(
// @import("path"): load and analyze an imported module.
// Returns the root struct type of the imported module.
- // Ported from src/Sema.zig:13764 zirImport.
+ // Ported from src/Sema.zig:13764 zirImport → pt.doImport.
case ZIR_INST_IMPORT: {
uint32_t pl = sema->code.inst_datas[inst].pl_tok.payload_index;
uint32_t path_idx = sema->code.extra[pl + 1];
const char* import_path
= (const char*)&sema->code.string_bytes[path_idx];
InternPoolIndex result = IP_INDEX_VOID_VALUE;
-
- 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.
- // 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,
- import_full, sizeof(import_full))) {
- uint32_t fid = ensureFileAnalyzedC(import_full);
- if (fid != UINT32_MAX)
- result = s_file_root_type[fid];
- }
- }
+ uint32_t fid = doImport(sema->source_dir, import_path);
+ if (fid != UINT32_MAX)
+ result = s_file_root_type[fid];
instMapPut(&sema->inst_map, inst, AIR_REF_FROM_IP(result));
i++;
continue;