Make Nimble compile again

This commit is contained in:
Araq
2026-07-02 12:10:40 +02:00
parent 343f7d0db2
commit 4c4b8ef966
2 changed files with 22 additions and 3 deletions

View File

@@ -2808,8 +2808,18 @@ proc materializeLazyBody*(c: var DecodeContext; node: PNode) =
node.typField = real.typField
node.flags = real.flags
forceLazyBodyHook = proc (n: PNode) {.nimcall.} =
if loaderCtx != nil: materializeLazyBody(loaderCtx[], n)
forceLazyBodyHook = proc (n: PNode) {.nimcall, raises: [], tags: [], gcsafe.} =
# `len` (the sole caller path) MUST stay effect-free, so this hook is typed
# `raises: []`. The underlying `loadNode` chain infers `raises: [KeyError]`
# (index/sym Table lookups), but materialization only ever runs for a body
# DEFERRED during THIS load — the buffer/index is present by construction, so a
# KeyError here means a corrupt cache: a fatal bug, not a recoverable error.
# Treat it as effect-free (a `Defect`-like invariant) via a scoped cast.
if loaderCtx != nil:
{.cast(raises: []).}:
{.cast(tags: []).}:
{.cast(gcsafe).}:
materializeLazyBody(loaderCtx[], n)
proc loadSymFromIndexEntry(c: var DecodeContext; module: FileIndex;
nifName: string; entry: NifIndexEntry; thisModule: string): PSym =

View File

@@ -906,11 +906,20 @@ const
defaultOffset* = -1
var forceLazyBodyHook*: proc (n: PNode) {.nimcall.}
var forceLazyBodyHook*: proc (n: PNode) {.nimcall, raises: [], tags: [], gcsafe.}
## Set by the IC loader (ast2nif). When a node carries `nfLazyBody`, any access
## to its children through `len` materializes the deferred routine body in place.
## `safeLen` delegates to `len`, so it is covered transitively; a lazy body is
## never a leaf kind, so the `{nkNone..nkNilLit}` short-circuit never hides it.
##
## The type MUST be effect-free (`raises: []`/`tags: []`): `len` is a fundamental
## `PNode` accessor that the whole compiler — and every compiler-as-library
## consumer (nimble, nimsuggest, ...) — assumes cannot raise. An unannotated
## `proc` var defaults to `raises: [Exception]`, so the indirect call tainted
## `len`/`safeLen`/`items` with `Exception`, breaking any iterator/`{.raises.}`
## over a `PNode` (e.g. nimble's `extract {.raises: [CatchableError].}`).
## Materialization is a pure in-memory buffer transform; a corrupt buffer is a
## `Defect` (`raiseAssert`), which is outside exception tracking.
proc len*(n: PNode): int {.inline.} =
if nfLazyBody in n.flags and forceLazyBodyHook != nil: