IC: codegen the main module in a single C translation unit

Under `nim nifc` the main module is loaded by its source FileIndex, but
its serialized symbols carry the module's NIF suffix, so
registerNifSuffix allocated a SECOND FileIndex for the same module:
top-level globals were emitted into the source-index BModule while
procs went into the suffix-index BModule, and a N_LIB_PRIVATE global
declared in one TU was undeclared in the other (tincremental,
tmacros_various).

Pre-aliasing the suffix to the source index in loadModuleDependencies
unifies the TUs. This was tried before and reverted: the split was
masking a hook C-name disamb collision between sem-lifted (loaded) and
codegen-lifted hooks in the same module. That collision class is gone
since backend-minted symbols mangle as _c<item> (BackendIdOffset), so
the unification is safe now.

Macro sweep 92/95 (fixes tincremental + tmacros_various; remaining:
tmacro7 which fails identically under non-IC and is disabled,
tmacrogenerics, tmacrogetimpl), tests/ic 5/5, clean koch bootic
reaches the bit-identical fixed point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Araq
2026-06-10 13:17:03 +02:00
parent 34b3893316
commit 5ce2c8f95d

View File

@@ -23,12 +23,18 @@ when defined(nimPreviewSlimSystem):
import std/assertions
import ast, options, lineinfos, modulegraphs, cgendata, cgen,
pathutils, extccomp, msgs, modulepaths, idents, types, ast2nif
pathutils, extccomp, msgs, modulepaths, idents, types, ast2nif, typekeys
import ic / replayer
proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PrecompiledModule] =
## Traverse the module dependency graph using a stack.
## Returns all modules that need code generation, in dependency order.
# The main module is loaded by its SOURCE FileIndex, but its serialized
# symbols carry the module's NIF suffix. Pre-alias the suffix to the source
# index so that `registerNifSuffix` does not allocate a second FileIndex for
# the same module, which would split its codegen across two C translation
# units (top-level globals in one, procs in the other → undeclared symbols).
g.config.m.filenameToIndexTbl[cachedModuleSuffix(g.config, mainFileIdx)] = mainFileIdx
let mainModule = moduleFromNifFile(g, mainFileIdx, {LoadFullAst})
var stack: seq[ModuleSuffix] = @[]