alternative to #24101 enabled in the context of the generic/template declarations capturing the symbols, not the context of the instantiation of the generics/templates. This was to be in line with where the compiler gives the warnings and changes behavior in a potentially breaking way. However `results` [depends on the old behavior](71d404b314/results.nim (L1428)), so that the callers of the macros provided by results always take advantage of the opensym behavior. To accomodate this, we change the behavior of the old experimental option that `results` uses, `genericsOpenSym`, so that ignores the information of whether or not symbols are intentionally opened and always gives the opensym behavior as long as it's enabled at instantiation time. This should keep `results` working as is. However this differs from the normal opensym switch in that it doesn't generate `nnkOpenSym`. Before it was just a generics-only version of `openSym` along with `templateOpenSym` which was only for templates. So `templateOpenSym` is removed along with this change, but no one appears to have used it. (cherry picked from commit0c3573e4a0)
4.1 KiB
v2.2.0 - yyyy-mm-dd
Changes affecting backward compatibility
-d:nimStrictDeletebecomes the default. An index error is produced when the index passed tosystem.deletewas out of bounds. Use-d:nimAuditDeleteto mimic the old behavior for backwards compatibility.- The default user-agent in
std/httpclienthas been changed toNim-httpclient/<version>instead ofNim httpclient/<version>which was incorrect according to the HTTP spec. - With
-d:nimPreviewNonVarDestructor, non-var destructors become the default.
Standard library additions and changes
- Added
newStringUninitto system, which creates a new string of lengthlenlikenewStringbut with uninitialized content. - Added
setLenUninitto system, which doesn't initalize slots when enlarging a sequence. - Added
hasDefaultValuetostd/typetraitsto check if a type has a valid default value. - Added Viewport API for the JavaScript targets in the
dommodule.
Language changes
-
The experimental option
--experimental:openSymhas been added to allow captured symbols in generic routine and template bodies respectively to be replaced by symbols injected locally by templates/macros at instantiation time.bindmay be used to keep the captured symbols over the injected ones regardless of enabling the option, but other methods like renaming the captured symbols should be used instead so that the code is not affected by context changes.Since this change may affect runtime behavior, the experimental switch
openSymneeds to be enabled; and a warning is given in the case where an injected symbol would replace a captured symbol not bound bybindand the experimental switch isn't enabled.const value = "captured" template foo(x: int, body: untyped): 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:openSym` echo old[int]() # "captured" template oldTempl(): string = block: foo(123): value # warning: a new `value` has been injected, use `bind` or turn on `experimental:openSym` echo oldTempl() # "captured" {.experimental: "openSym".} 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" template barTempl(): string = block: foo(123): value assert barTempl() == "injected" # previously it would be "captured" template bazTempl(): string = bind value block: foo(123): value assert bazTempl() == "captured"This option also generates a new node kind
nnkOpenSymwhich contains exactly 1nnkSymnode. In the future this might be merged with a slightly modifiednnkOpenSymChoicenode but macros that want to support the experimental feature should still handlennkOpenSym, as the node kind would simply not be generated as opposed to being removed.Another experimental switch
genericsOpenSymexists that enables this behavior at instantiation time, meaning templates etc can enable it specifically when they are being called. However this does not generatennkOpenSymnodes (unless the other switch is enabled) and so doesn't reflect the regular behavior of the switch.const value = "captured" template foo(x: int, body: untyped): untyped = let value {.inject.} = "injected" {.push experimental: "genericsOpenSym".} body {.pop.} proc bar[T](): string = foo(123): return value echo bar[int]() # "injected" template barTempl(): string = block: var res: string foo(123): res = value res assert barTempl() == "injected"
Compiler changes
Tool changes
- koch now allows bootstrapping with
-d:nimHasLibFFI, replacing the older option of building the compiler directly w/ thelibffinimble package in tow.