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>
This commit is contained in:
2026-03-01 14:12:03 +00:00
parent dc67c0c21e
commit d2d3c55d51

View File

@@ -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;
}
}
}
}