Files
Nim/changelog.md
Zoom bd95f88f74 js: fix var openArray write-through for toOpenArray (#26086)
In the JS backend `toOpenArray` used `slice` (a copy), so writes through
a `var openArray` parameter silently vanished.

This emits `subarray` (a live shared-buffer view) for homogeneous
numeric arrays, otherwise such parameters are passed as a `{base, off,
len}` view that always aliases the caller's storage. Sliced seq/array
args become `{base, off, len}`, whole values `{base, off:0, len}`,
re-slices rebase.

Un-skips the JS guard in tests/openarray/topenarray.nim 
Fixes #15952.
2026-08-26 18:01:06 +02:00

8.6 KiB

v2.x.x - yyyy-mm-dd

Changes affecting backward compatibility

  • -d:nimPreviewFloatRoundtrip becomes the default. system.addFloat and system.$ now can produce string representations of floating point numbers that are minimal in size and possess round-trip and correct rounding guarantees (via the Dragonbox algorithm). Use -d:nimLegacySprintf to emulate old behaviors.

  • The default parameter of tables.getOrDefault has been renamed to def to avoid conflicts with system.default, so named argument usage for this parameter like getOrDefault(..., default = ...) will have to be changed.

  • With -d:nimPreviewCheckedClose, the close function in the std/syncio module now raises an IO exception in case of an error.

  • Unknown warnings and hints now gives warnings warnUnknownNotes instead of errors.

  • With -d:nimPreviewAsmSemSymbol, backticked symbols are type checked in the asm/emit statements.

  • The bare except: now panics on Defect. Use except Exception: or except Defect: to catch Defect. --legacy:noPanicOnExcept is provided for a transition period.

  • With -d:nimPreviewCStringComparisons, comparsions (<, >, <=, >=) between cstrings switch from reference semantics to value semantics like == and !=.

  • std/parsesql has been moved to a nimble package, use nimble or atlas to install it.

  • With -d:nimPreviewDuplicateModuleError, importing two modules that share the same name becomes a compile-time error. This includes importing the same module more than once. Use import foo as foo1 (or other aliases) to avoid collisions.

  • Adds the switch --mangle:nim|cpp, which selects nim or cpp style name mangling when used with debuginfo on, defaults to cpp.

  • The second parameter of succ, pred, inc, and dec in system now accepts SomeInteger (previously Ordinal).

  • Bitshift operators (shl, shr, ashr) now apply bitmasking to the right operand in the C/C++/VM/JS backends.

  • Adds a new warning --warning:ImplicitRangeConversion that detects downsizing implicit conversions to range types (e.g., int -> range[0..255] or range[1..256] -> range[0..255]) that could cause runtime panics. Safe conversions like range[0..255] -> range[0..65535] and explicit casts do not trigger warnings. int to Natural and Positive conversions do not trigger warnings, which can be enabled with --warning:systemRangeConversion.

  • Procedure compatibility also checks the backend representation of the parameter and result types, not just their source-level shape. Use --legacy:procParamTypeBackendAliases to restore the older behavior.

Standard library additions and changes

  • Added system.readRawDataStable, a companion to readRawData that returns a raw ptr UncheckedArray[char] into a string's character data which stays valid across moves and copies of the string value. It is available under every string implementation (refc, ARC/ORC and --strings:sso) with the same signature, so code can pin an interior buffer pointer today and be ready for --strings:sso without when declared guards. Under --strings:sso it promotes a small inline string to its heap representation first; under the other implementations the data is already heap-resident, so it is equivalent to readRawData.

  • setutils.symmetricDifference along with its operator version setutils.`-+-` and in-place version setutils.toggle have been added to more efficiently calculate the symmetric difference of bitsets.

  • strutils.multiReplace overload for character set replacements in a single pass. Useful for string sanitation. Follows existing multiReplace semantics.

  • std/files adds:

    • Exports CopyFlag enum and FilePermission type for fine-grained control of file operations
    • New file operation procs with Path support:
      • getFilePermissions, setFilePermissions for managing permissions
      • tryRemoveFile for file deletion
      • copyFile with configurable buffer size and symlink handling
      • copyFileWithPermissions to preserve file attributes
      • copyFileToDir for copying files into directories
  • std/dirs adds:

    • New directory operation procs with Path support:
      • copyDir with special file handling options
      • copyDirWithPermissions to recursively preserve attributes
  • system.setLenUninit now supports refc, JS and VM backends.

  • system.setLenUninit for the string type. Allows setting length without initializing new memory on growth.

  • std/parseopt now supports multiple parser modes via a CliMode enum. Modes include Nim (default, fully compatible) and two new experimental modes: Lax and Gnu for different option parsing behaviors.

  • std/symlinks.expandSymlink now supports Windows symlinks and junctions with POSIX-like single-hop readlink semantics.

  • std/nre2 is added to replace deprecated NRE.

  • system.typeof adds a new parameter modifierMode to specify how type modifiers are handled.

  • std/math The ^ symbol now supports floating-point as exponent in addition to the Natural type.
  • min, max, and sequtils' minIndex, maxIndex and minmax for openArrays now accept a comparison function.
  • system.substr implementation now uses copymem (wrapped C memcpy) for copying data, if available at compilation.
  • system.newStringUninit is now considered free of side-effects allowing it to be used with --experimental:strictFuncs.
  • std/re and std/nre are deprecated as PCRE library is obsolete. Use https://github.com/nitely/nim-regex or std/nre2. See: https://github.com/nim-lang/Nim/issues/23668.
  • std/pegs now correctly lexes UTF-8 bytes inside bare identifier-style terminals, so case-insensitive matching of non-ASCII terms (e.g. \i café) works without single-quoting.
  • std/uri: The ? operator now appends query parameters to an existing query string instead of replacing it. Fixes #19782.
  • std/jsonutils: fromJson now throws an exception when converting to array/seq if the JSON isn't an array instead of silently failing

Language changes

  • An experimental option --experimental:typeBoundOps has been added that implements the RFC https://github.com/nim-lang/RFCs/issues/380. This makes the behavior of interfaces like hash, $, == etc. more reliable for nominal types across indirect/restricted imports.

    # objs.nim
    import std/hashes
    
    type
      Obj* = object
        x*, y*: int
        z*: string # to be ignored for equality
    
    proc `==`*(a, b: Obj): bool =
      a.x == b.x and a.y == b.y
    
    proc hash*(a: Obj): Hash =
      $!(hash(a.x) &! hash(a.y))
    
    # main.nim
    {.experimental: "typeBoundOps".}
    from objs import Obj # objs.hash, objs.`==` not imported
    import std/tables
    
    var t: Table[Obj, int]
    t[Obj(x: 3, y: 4, z: "debug")] = 34
    echo t[Obj(x: 3, y: 4, z: "ignored")] # 34
    

    See the experimental manual for more information.

  • Seven more Unicode characters are now parsed as operators, implementing the RFC https://github.com/nim-lang/RFCs/issues/571: ⟑ ⟇ ⩓ ⩔ ■ □ ☆. They all have the same priority as * (multiplication). As with the other Unicode operators, Nim only lexes them; their meaning is up to user code.

Compiler changes

  • Fixed a bug where sizeof(T) inside a typedesc template called from a generic type's when clause would error with "'sizeof' requires '.importc' types to be '.completeStruct'". The issue was that hasValuelessStatics in semtypinst.nim didn't recognize tyTypeDesc(tyGenericParam) as an unresolved generic parameter.

  • The JS backend now implements write-through for var openArray parameters that receive a toOpenArray view (bug #15952): mutations reach the caller's storage instead of silently writing to a copy. Fixed homogeneous numeric arrays (array[N, T], JS typed arrays) slice via subarray; seq and non-numeric arrays slice via a {base, off, len} view. This also covers seq/non-numeric-array write-through, pass-through, re-slicing and @ (openArray-to-seq) of such views.

Tool changes

  • Added --raw flag when generating JSON docs to not render markup.
  • Added --stdinfile flag to name of the file used when running program from stdin (defaults to stdinfile.nim)
  • Added --styleCheck:warning flag to treat style check violations as warnings.

Documentation changes

  • Added documentation for the completeStruct pragma in the manual.