docs: correct the Delegating bind statements example (fixes #19240) (#25890)

Fixes #19240.

The Manual's "Delegating bind statements" example didn't compile (module
B didn't import A, type `O` wasn't exported, and `x: T` couldn't bind to
`var O`), and once those were fixed it compiled *without* the `bind`
statement — so it didn't demonstrate delegating bind at all.

This replaces it with a minimal example that genuinely requires `bind
init`: `module main` imports A and B but not C, so `init` is not in
scope at the final instantiation of `genericA`; the open `mixin` symbol
fails to resolve without `bind init` forwarding it from module B.
Verified to fail without `bind` and compile with `bind` under Nim
2.2.10.

---
Disclosure: I work with Claude as a co-processor. I understand what I'm
submitting and I verified the example against the compiler myself. If
you prefer human-only contributions, just say so and I'll close without
friction.
This commit is contained in:
Aleksei Rybnikov
2026-06-13 05:54:19 -05:00
committed by GitHub
parent 587f90a816
commit c292ab987b

View File

@@ -6123,40 +6123,48 @@ instantiations cross multiple different modules:
```nim
# module A
type O* = object
proc genericA*[T](x: T) =
mixin init
init(x)
```
```nim
# module C
import A
proc init*(x: O) = discard
```
```nim
import C
# module B
import A, C
proc genericB*[T](x: T) =
# Without the `bind init` statement C's init proc is
# not available when `genericB` is instantiated:
# Without the `bind init` statement, C's `init` proc is not
# available when `genericA` is instantiated through `genericB`
# from `module main`, which does not import C:
bind init
genericA(x)
```
```nim
# module C
type O = object
proc init*(x: var O) = discard
```
```nim
# module main
import B, C
import A, B
genericB O()
genericB(O())
```
In module B has an `init` proc from module C in its scope that is not
taken into account when `genericB` is instantiated which leads to the
instantiation of `genericA`. The solution is to `forward`:idx: these
symbols by a `bind` statement inside `genericB`.
Because `genericA` uses `mixin init`, `init` is an open symbol that is
resolved when `genericA` is instantiated. Here `genericA` is instantiated
through `genericB`, whose final instantiation happens in `module main`.
Since `module main` does not import `module C`, `init` is not in scope at
that point, and the instantiation fails with ``undeclared identifier: 'init'``.
The `bind init` statement inside `genericB` forwards the `init` symbol that
is visible in `module B` into the instantiation of `genericA`, which makes
the example compile. This `bind`, which re-exposes a symbol to a nested
generic instantiation, is a `delegating bind`:idx:.
Templates