commit d2d3c55d51da516989b3cbcc97da2d1c910df12b (tree)
parent dc67c0c21e1493f0f4762da3d1de6de1f34b7f6d
Author: Motiejus <motiejus@jakstys.lt>
Date: Sun, 1 Mar 2026 14:12:03 +0000
sema: resolve imports and local decls in non-comptime DECL_VAL
Previously DECL_VAL/DECL_REF in non-comptime context only loaded
import side effects but returned void. This prevented cross-module
field_call chains (e.g. common.fneg(a)) from resolving in function
bodies.
Now non-comptime DECL_VAL resolves imports to their struct type and
local declarations to their nav value, matching how the Zig compiler
resolves declarations regardless of comptime context.
Next blocker: neghf2.__neghf2 inline expansion of common.fneg fails
with a resolveInst miss — the FIELD_CALL arg references param_anytype
instruction 1031 which isn't in the inline call's inst_map. The
cross-module inline param mapping needs to handle the caller's ZIR
instruction indices correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -11403,12 +11403,33 @@ static bool analyzeBodyInner(
}
}
}
- } else if (sema->source_dir && decl_name_idx != 0) {
- // Non-comptime: just load import side effects.
+ } else if (decl_name_idx != 0 && sema->file_idx != UINT32_MAX) {
+ // Non-comptime: resolve imports and local declarations.
+ // Import values are needed for field_val/call chains
+ // (e.g. common.fneg(a) in function bodies).
+ const char* decl_name
+ = (const char*)&sema->code.string_bytes[decl_name_idx];
const char* import_path
= findDeclImportPath(sema, decl_name_idx);
- if (import_path) {
- (void)doImport(sema->source_dir, import_path);
+ if (import_path && sema->source_dir) {
+ uint32_t fid = doImport(sema->source_dir, import_path);
+ if (fid != UINT32_MAX)
+ resolved = s_file_root_type[fid];
+ } else if (!import_path) {
+ // Local declaration: look up in file namespace.
+ uint32_t ns_idx = s_file_namespace[sema->file_idx];
+ uint32_t nav = findNavInNamespace(ns_idx, decl_name);
+ if (nav != UINT32_MAX) {
+ if (s_in_main_analysis) {
+ InternPoolIndex val = ensureNavValUpToDate(nav);
+ if (val != IP_INDEX_NONE)
+ resolved = val;
+ } else {
+ const Nav* n = ipGetNav(nav);
+ if (n->resolved_type != IP_INDEX_NONE)
+ resolved = n->resolved_type;
+ }
+ }
}
}