From 5ce2c8f95dfeae0cc9123a38bb279fea2e400368 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Jun 2026 13:17:03 +0200 Subject: [PATCH] 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 (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 --- compiler/nifbackend.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/nifbackend.nim b/compiler/nifbackend.nim index ecead9edc3..e3ea99f861 100644 --- a/compiler/nifbackend.nim +++ b/compiler/nifbackend.nim @@ -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] = @[]