summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2023-12-22 10:49:51 +0300
committerGitHub <noreply@github.com>2023-12-22 08:49:51 +0100
commit4b1a84170786653f60313f7bdf56efa3928c2a3a (patch)
treedb7898a3be349b1b42cc4cb566d5a8587c6d37b2 /doc
parentdf3c95d8af7bfd1e61e6b06eec21f57781dff9d5 (diff)
downloadNim-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.md40
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
 ==================