summary refs log tree commit diff stats
path: root/changelog.md
blob: dfbddeaa6cd995deb60f8156f0e889966e0f7dbd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# v2.2.0 - yyyy-mm-dd


## Changes affecting backward compatibility

- `-d:nimStrictDelete` becomes the default. An index error is produced when the index passed to `system.delete` is out of bounds. Use `-d:nimAuditDelete` to mimic the old behavior for backward compatibility.
- The default user-agent in `std/httpclient` has been changed to `Nim-httpclient/<version>` instead of `Nim httpclient/<version>` which was incorrect according to the HTTP spec.
- Methods now support implementations based on a VTable by using `--experimental:vtables`. Methods are then confined to the same module where their type has been defined.
- With `-d:nimPreviewNonVarDestructor`, non-var destructors become the default.
- A bug where tuple unpacking assignment with a longer tuple on the RHS than the LHS was allowed has been fixed, i.e. code like:
  ```nim
  var a, b: int
  (a, b) = (1, 2, 3, 4)
  ```
  will no longer compile.
- `internalNew` is removed from the `system` module, use `new` instead.

- `bindMethod` in `std/jsffi` is deprecated, don't use it with closures.

- JS backend now supports lambda lifting for closures. Use `--legacy:jsNoLambdaLifting` to emulate old behaviors.

- JS backend now supports closure iterators.

- `owner` in `std/macros` is deprecated.

- Ambiguous type symbols in generic procs and templates now generate symchoice nodes.
  Previously; in templates they would error immediately at the template definition,
  and in generic procs a type symbol would arbitrarily be captured, losing the
  information of the other symbols. This means that generic code can now give
  errors for ambiguous type symbols, and macros operating on generic proc AST
  may encounter symchoice nodes instead of the arbitrarily resolved type symbol nodes.

- Partial generic instantiation of routines is no longer allowed. Previously
  it compiled in niche situations due to bugs in the compiler.

  ```nim
  proc foo[T, U](x: T, y: U) = echo (x, y)
  proc foo[T, U](x: var T, y: U) = echo "var ", (x, y)

  proc bar[T]() =
    foo[float](1, "abc")

  bar[int]() # before: (1.0, "abc"), now: type mismatch, missing generic parameter
  ```

- `const` values now open a new scope for each constant, meaning symbols
  declared in them can no longer be used outside or in the value of
  other constants.

  ```nim
  const foo = (var a = 1; a)
  const bar = a # error
  let baz = a # error
  ```
- The following POSIX wrappers have had their types changed from signed to
  unsigned types on OSX and FreeBSD/OpenBSD to correct codegen errors:
  - `Gid` (was `int32`, is now `uint32`)
  - `Uid` (was `int32`, is now `uint32`)
  - `Dev` (was `int32`, is now `uint32` on FreeBSD)
  - `Nlink` (was `int16`, is now `uint32` on OpenBSD and `uint16` on OSX/other BSD)
  - `sin6_flowinfo` and `sin6_scope_id` fields of `Sockaddr_in6`
    (were `int32`, are now `uint32`)
  - `n_net` field of `Tnetent` (was `int32`, is now `uint32`)


## Standard library additions and changes

[//]: # "Changes:"

- Changed `std/osfiles.copyFile` to allow specifying `bufferSize` instead of a hard-coded one.
- Changed `std/osfiles.copyFile` to use `POSIX_FADV_SEQUENTIAL` hints for kernel-level aggressive sequential read-aheads.
- `std/htmlparser` has been moved to a nimble package, use `nimble` or `atlas` to install it.
- Changed `std/os.copyDir` and `copyDirWithPermissions` to allow skipping special "file" objects like FIFOs, device files, etc on Unix by specifying a `skipSpecial` parameter.

[//]: # "Additions:"

- Added `newStringUninit` to the `system` module, which creates a new string of length `len` like `newString` but with uninitialized content.
- Added `setLenUninit` to the `system` module, which doesn't initialize
slots when enlarging a sequence.
- Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
- Added `rangeBase` to `std/typetraits` to obtain the base type of a range type or
  convert a value with a range type to its base type.
- Added Viewport API for the JavaScript targets in the `dom` module.
- Added `toSinglyLinkedRing` and `toDoublyLinkedRing` to `std/lists` to convert from `openArray`s.
- ORC: To be enabled via `nimOrcStats` there is a new API called `GC_orcStats` that can be used to query how many
  objects the cyclic collector did free. If the number is zero that is a strong indicator that you can use `--mm:arc`
  instead of `--mm:orc`.
- A `$` template is provided for `Path` in `std/paths`.
- `std/hashes.hash(x:string)` changed to produce a 64-bit string `Hash` (based
on Google's Farm Hash) which is also often faster than the present one.  Define
`nimStringHash2` to get the old values back.  `--jsbigint=off` mode always only
produces the old values.  This may impact your automated tests if they depend
on hash order in some obvious or indirect way.  Using `sorted` or `OrderedTable`
is often an easy workaround.

[//]: # "Deprecations:"

- Deprecates `system.newSeqUninitialized`, which is replaced by `newSeqUninit`.

[//]: # "Removals:"


## Language changes

- `noInit` can be used in types and fields to disable member initializers in the C++ backend.
- C++ custom constructors initializers see https://nim-lang.org/docs/manual_experimental.html#constructor-initializer
- `member` can be used to attach a procedure to a C++ type.
- C++ `constructor` now reuses `result` instead creating `this`.

- Tuple unpacking changes:
  - Tuple unpacking assignment now supports using underscores to discard values.
    ```nim
    var a, c: int
    (a, _, c) = (1, 2, 3)
    ```
  - Tuple unpacking variable declarations now support type annotations, but
    only for the entire tuple.
    ```nim
    let (a, b): (int, int) = (1, 2)
    let (a, (b, c)): (byte, (float, cstring)) = (1, (2, "abc"))
    ```

- The experimental option `--experimental:openSym` has 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. `bind` may 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
  `openSym` 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): 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 `nnkOpenSym` which contains
  exactly 1 `nnkSym` node. In the future this might be merged with a slightly
  modified `nnkOpenSymChoice` node but macros that want to support the
  experimental feature should still handle `nnkOpenSym`, as the node kind would
  simply not be generated as opposed to being removed.

  Another experimental switch `genericsOpenSym` exists that enables this behavior
  at instantiation time, meaning templates etc can enable it specifically when
  they are being called. However this does not generate `nnkOpenSym` nodes
  (unless the other switch is enabled) and so doesn't reflect the regular
  behavior of the switch.

  ```nim
  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

- `--nimcache` using a relative path as the argument in a config file is now relative to the config file instead of the current directory.

## 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.