IC: record that the lazy interfHidden conversion does not work yet

Tried it. The shape is easy and it is not the problem: `modulegraphs`
already imports `ast2nif` so no callback hook is needed, every read of
`interfHidden` goes through `interfSelect`, and its four call sites all
have the graph and the module to hand.

It builds, and it keeps privacy — a plain `import` still rejects a
private symbol under both `--ic:on` and `--ic:off`. But `import x {.all.}`
then fails under `--ic:on` with "undeclared identifier", where it works
today and works under `--ic:off`. Silent, and entangled with the driver's
discovery loop: the module is not in `DecodeContext.mods` when the lookup
asks, on a cold cache and on a warm one alike.

Three fixes tried, none of them it, recorded in `bnode.nim` so nobody
re-guesses them: clearing `hiddenPending` only on success (necessary, not
sufficient — one early miss otherwise costs the module its hidden symbols
for the whole process); loading the module inside the lazy builder rather
than assuming the caller did; and building into a local `TStrTable` in
case the `var` alias into `g.ifaces` was being invalidated by the seq
growing underneath it. After all three, `ensureHiddenIface` still reports
the module missing on every one of its 19 calls.

So the next attempt starts by instrumenting `moduleId`'s FileIndex
against `moduleFromNifFile`'s — whatever sets `hiddenPending` and
whatever fills `c.mods` are not agreeing about which module they mean —
before any more of the mechanism gets written. The 1.05s is still there
and still worth having.

Comment-only. ic 41/41.
This commit is contained in:
araq
2026-08-31 19:00:48 +02:00
parent 3f014bbd37
commit f48efa4b1f

View File

@@ -147,8 +147,37 @@
## the whole Atlas build 22.19s -> 20.47s. Doing it CORRECTLY means populating
## the table lazily on first `interfSelect(true)` rather than deciding
## up front — a macro-generated `{.all.}` import cannot be seen syntactically,
## and guessing wrong loses symbols silently. `loaderCtx` is the hook: the
## module index is still in the DecodeContext after loading.
## and guessing wrong loses symbols silently.
##
## That lazy conversion has been ATTEMPTED and does not work as a
## substitution. The shape is easy: `modulegraphs` already imports `ast2nif`
## (the dependency runs that way, so no callback hook is needed), every read of
## `interfHidden` goes through `interfSelect`, and its 4 call sites all have
## the graph and the module to hand. It builds and it keeps privacy — a plain
## `import` still rejects a private symbol under both `--ic:on` and
## `--ic:off` — but `import x {.all.}` then fails under `--ic:on` with
## "undeclared identifier", where it works today and works under `--ic:off`.
## The failure is silent and it is entangled with the driver's discovery loop:
## the module is not in `DecodeContext.mods` at the point the lookup asks, on
## a COLD cache and on a warm one.
##
## Three fixes were tried and none of them is it, recorded so nobody
## re-guesses them:
## * clearing `hiddenPending` only when the build SUCCEEDS, so an import
## whose `.s.bif` does not exist yet is retried rather than written off.
## Necessary — one early miss otherwise costs the module its hidden
## symbols for the whole process — but not sufficient.
## * loading the module inside the lazy builder (`moduleId` is idempotent)
## instead of assuming the caller already did.
## * building into a LOCAL `TStrTable` and assigning it back, in case the
## `var` alias into `g.ifaces` was being invalidated by the seq growing
## during the load.
## After all three, `ensureHiddenIface` still reports the module missing from
## `DecodeContext.mods` on every one of its 19 calls. Whatever populates
## `hiddenPending` and whatever populates `c.mods` are not agreeing about
## which module they mean, and that is where the next attempt should start —
## with `moduleId`'s FileIndex against `moduleFromNifFile`'s, instrumented at
## both ends, before any more of the mechanism is written.
## * `-d:icBridgeOnly` builds the buffer but generates off the tree, which
## separates the ENCODER's cost from the READER's. Encoding is free — it does
## not show in wall time at all.