diff options
author | metagn <metagngn@gmail.com> | 2023-12-22 10:49:51 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-22 08:49:51 +0100 |
commit | 4b1a84170786653f60313f7bdf56efa3928c2a3a (patch) | |
tree | db7898a3be349b1b42cc4cb566d5a8587c6d37b2 /doc | |
parent | df3c95d8af7bfd1e61e6b06eec21f57781dff9d5 (diff) | |
download | Nim-4b1a84170786653f60313f7bdf56efa3928c2a3a.tar.gz |
add switch, warning, and `bind` support for new generic injection behavior (#23102)
refs #23091, especially post merge comments Unsure if `experimental` and `bind` are the perfect constructs to use but they seem to get the job done here. Symbol nodes do not get marked `nfOpenSym` if the `bind` statement is used for their symbol, and `nfOpenSym` nodes do not get replaced by new local symbols if the experimental switch is not enabled in the local context (meaning it also works with `push experimental`). However this incurs a warning as the fact that the node is marked `nfOpenSym` means we did not `bind` it, so we might want to do that or turn on the experimental switch if we didn't intend to bind it. The experimental switch name is arbitrary and could be changed. --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual_experimental.md | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md index fc5ff1959..765a69a0f 100644 --- a/doc/manual_experimental.md +++ b/doc/manual_experimental.md @@ -2521,6 +2521,46 @@ NimFunctor()(1) Notice we use the overload of `()` to have the same semantics in Nim, but on the `importcpp` we import the functor as a function. This allows to easy interop with functions that accepts for example a `const` operator in its signature. + +Injected symbols in generic procs +================================= + +With the experimental option `genericsOpenSym`, captured symbols in generic +routine bodies may be replaced by symbols injected locally by templates/macros +at instantiation time. `bind` may be used to keep the captured symbols over +the injected ones regardless of enabling the option. + +Since this change may affect runtime behavior, the experimental switch +`genericsOpenSym` needs to be enabled, and a warning is given in the case +where an injected symbol would replace a captured symbol not bound by `bind` +and the experimental switch isn't enabled. + +```nim +const value = "captured" +template foo(x: int, body: untyped) = + let value {.inject.} = "injected" + body + +proc old[T](): string = + foo(123): + return value # warning: a new `value` has been injected, use `bind` or turn on `experimental:genericsOpenSym` +echo old[int]() # "captured" + +{.experimental: "genericsOpenSym".} + +proc bar[T](): string = + foo(123): + return value +assert bar[int]() == "injected" # previously it would be "captured" + +proc baz[T](): string = + bind value + foo(123): + return value +assert baz[int]() == "captured" +``` + + VTable for methods ================== |