Files
Nim/changelog.md
metagn a16f126614 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>
(cherry picked from commit 4b1a841707)
2024-05-03 07:32:19 +02:00

1.9 KiB

v2.2.0 - yyyy-mm-dd

Changes affecting backward compatibility

Standard library additions and changes

  • Added newStringUninit to system, which creates a new string of length len like newString but with uninitialized content.
  • Added setLenUninit to system, which doesn't initalize slots when enlarging a sequence.
  • Added hasDefaultValue to std/typetraits to check if a type has a valid default value.
  • Added Viewport API for the JavaScript targets in the dom module.

Language changes

  • An experimental option genericsOpenSym has been added to allow captured symbols in generic routine bodies to 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.

    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"
    

Compiler changes

Tool changes

  • koch now allows bootstrapping with -d:nimHasLibFFI, replacing the older option of building the compiler directly w/ the libffi nimble package in tow.