Commit Graph

8871 Commits

Author SHA1 Message Date
ringabout
f3b04ccd87 fixes #26152; JS regression: dockhack.js is invalid 2026-08-31 22:50:58 +08:00
Ryan McConnell
8cb406cd7a Fix 26144; exception propagation for non-raising virtual methods (#26145)
ref #26144 

The C backend must not use `sfNeverRaises` to remove exception checks
from
virtual method calls. The flag describes only the selected base method
body,
while a vtable override may raise a catchable exception.

This change makes `canRaiseDisp` conservative for `skMethod` symbols and
adds a
regression test covering an exception raised by a child method invoked
through a
base reference.
2026-08-29 14:41:05 +02:00
ringabout
802bcf5a2d fixes #26132; =destroy should accept non-parametrized generic (#26142)
fixes  #26132
2026-08-29 14:40:46 +02:00
Ryan McConnell
33ee586913 fixes #11797; fix C type hashes for imported aliases (#26150)
Fixes #11797.

Imported scalar and pointer aliases inherit their external C spelling,
but
receive a different Nim symbol. Signature hashing previously used that
symbol
identity, so aliases that emit exactly the same C type could produce
different
  backend names for tuples, sequences, and other generic types.

  For example, `cint` and `type CIntAlias = cint` both emit `int`, but
`seq[cint]` and `seq[CIntAlias]` could be emitted as incompatible C
structs.
The Nim type checker nevertheless permits assignments and calls between
them,
  causing the generated C or C++ compilation to fail.

This changes the backend hash to use the external type spelling when
available.
A symbol-based fallback remains for imported types without a resolved
spelling.

The change deliberately does not collapse imported types into their
underlying
Nim builtin. Types such as `pid_t`, imported pointers with qualifiers,
and
  platform typedefs may require distinct backend representations.

  ## NIF and incremental compilation

This does not change NIF serialization, NIF type keys, or the IC cache
format.
The bug is in backend type-name generation. An IC regression test is
included
to ensure that the corrected backend identity is preserved when
compilation
  passes through the NIF pipeline.

  ## Tests

  The regressions cover:

- tuple and sequence assignments between an imported type and its alias
  - cross-module sequence parameters and mutation
  - C and C++ backends
  - NIF-backed incremental compilation

  Existing C-type tests were also run under C/C++, refc, and ARC.

  ## Remaining scope

This does not solve the broader question of compatibility between
imported and
  builtin types that have different backend identities, such as
  `seq[cdouble]` and `seq[float]`. That remains tracked by #19374.
2026-08-28 22:33:20 +02:00
Ryan McConnell
0be9b4f3f6 fix 26147; new-style concepts: broken generic (Case B) (#26151)
ref #26147
2026-08-28 22:31:58 +02:00
ringabout
c36c527db3 fixes #26143; Possible memory error (#26154)
fixes #26143

follows up https://github.com/nim-lang/Nim/pull/20307
2026-08-28 22:26:18 +02:00
Andreas Rumpf
c87926dadf IC: more bugfixes (#26141)
Grinding a small figdraw-based program under `nim ic` and diffing its
output against the classic backend surfaced eight bugs, four of which
silently produced a wrong binary rather than an error.

Frontend / build graph (`deps.nim`):

* Dead `when`-guarded imports were compiled anyway. `when someStrdefine
== "x": import y` is `cvUnknown` to the scanner, which conservatively
keeps the edge — right for an edge, but it also gave `y` its own `nim m`
rule, so a build died on a package the user never installed because they
never selected that backend. Track which edges are speculative and drop
a speculative subtree that cannot compile; if the guard was in fact
live, the discovery fixpoint puts the node back with the honest `cannot
open file`.
* Deleting a still-imported module went unnoticed: no mtime moves, so
nothing re-fires and `nim ic` relinked a stale binary while `nim c`
reported `cannot open file`. Report an unresolvable import from a
non-speculatively reached module during the graph scan.
* Macro-generated imports were discovered once and then forgotten.
Discovery only ran after a failure and the graph is re-derived
statically every run, so on a warm build the discovered module had no
rules at all and editing it changed nothing. Seed the graph from the
`.s.deps` sidecars up front.
* Config changes invalidated nothing. nifmake decides staleness from
file mtimes and never looks at a rule's command line, so `-d:foo=bar` /
`--mm:` / `--threads:` regenerated the build file with the new switches
and re-fired zero rules. Reify the configuration as a file and make it
an input of every rule.
* Command-line switches never reached the children: they replay the
project's config files, never the driver's argv, so `nim ic --opt:speed`
produced a byte-identical debug binary (likewise `--panics`,
`--experimental`, `--passC`). Forward the driver's switches, minus the
ones that must differ per child.

Artifacts and codegen:

* A failed `nim m` still wrote its `.s.bif` and cookies, so nifmake saw
the rule as satisfied on the next run: `nim ic` then reported success
for a program that does not compile, and generated code from
error-bearing AST (or hit an internal error in `ccgexprs`). Never
persist an artifact when `errorCounter > 0`.
* Top-level destructors were never injected. `sfInjectDestructors` lives
on the module symbol, which `moduleFromNifFile` rebuilds from scratch,
so `genTopLevelStmt` skipped `injectDestructorCalls` entirely: a
module-level `block: let h = openHandle()` never ran `=destroy`. Persist
the flag as a `(modflags)` record. `injectdestructors` also has to
tolerate the `nkReplayAction` entries the loader prepends to `topLevel`.
* `nfFirstWrite` / `nfLastRead` were dropped by the serializer. A sym
node is written as a bare NIF `SymUse` token, which has nowhere to put
node flags, so the frontend's move analysis never reached the backend:
EVERY first assignment to a destructor-bearing local compiled as
`=sink`, i.e. `=destroy` on still-zeroed memory followed by a copy, and
no read was ever a move. Wrap a sym use in `(nflags ...)` when it
carries persistent node flags.
2026-08-27 19:35:11 +02:00
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
ringabout
dc242e9027 fixes #26124; internal error: expr: param not init with nested generic procs (#26131)
fixes #26124

The fix preserves the resolved static value, allowing constant folding.

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2026-08-26 08:40:57 +02:00
Andreas Rumpf
8ca7b75b8b refactoring: better IC + no unique Id (#26137) 2026-08-25 11:59:19 +02:00
ringabout
2d1412a2ea fixes #26015; Multiple definition error when using codegenDecl regression (#26018)
fixes #26015

Fixes imported global variables with codegenDecl being emitted as
definitions instead of extern declarations.

A variable’s codegenDecl format should customize its definition in the
owning module. Other modules referencing the variable must emit a normal
declaration:

```c
extern NI variable;
```

After the variable-declaration builder refactor, genVarPrototype passed
Extern visibility to addVar. However, the sfCodegenDecl branch returned
before applying that visibility. This caused importing modules to emit
another tentative definition, resulting in duplicate-symbol linker
errors.

The fix restores the previous distinction between the custom definition
and cross-module prototypes. It also adds C and C++ regression coverage
for both direct access and access through an inline procedure.

follows up https://github.com/nim-lang/Nim/pull/24423
2026-08-23 12:37:15 +02:00
ringabout
f1256ddcf4 fixes #26123; Update PathKinds1 to include nkCast (#26126)
fixes #26123

`cast[T](x)` is a transparent path expression for compiler analysis.
Previously, move/alias analysis could fail to see a later use through a
cast and incorrectly mark the source as moved, causing the issue’s
segmentation fault.


for views,
https://nim-lang.org/docs/manual_experimental.html#view-types-path-expressions:
A cast expression cast[T](e) is a path expression.

It also affects skipConvDfa, isAnalysableFieldAccess, and aliases. And I
might narrow it down for the two cases above mentioned if it causes
problems
2026-08-21 21:57:51 +08:00
SirOlaf
901ca7905a IC: Do not serialize nfHasComment to nif (#26127)
It causes non-deterministic behavior because it's process-local.
2026-08-20 18:11:31 +02:00
ringabout
1201c184d7 fix #26112: update variable kinds in isPartOf to include skResult (#26114)
fix #26112
2026-08-17 23:37:46 +02:00
Jacek Sieka
5f5cf8dd03 rm some cruft (#26113)
`XDeclaredButNotUsed` for years in most cases - there's more but this is
the low-hanging fruit
2026-08-17 15:02:49 +02:00
ringabout
16920b56d1 fixes #25992; fix GC tracing of stale bytes in case objects during reset (#26003)
fixes #25992
```nim
type
  Foo = object
    case kind: bool
    of true:
      a: ref Bar   # 8 bytes (pointer)
    of false:
      b: int       # 4 bytes
```
specializeResetT for b emits accessor.b = 0 — writes 4 bytes
But the union is 8 bytes wide (sized by the largest branch)
The remaining 4 bytes where a used to live are untouched
Those stale bytes could contain a heap pointer the GC traces → crash

Add nimZeroMem after specializeResetN for case objects to clear the
entire union including unused branch bytes.
2026-08-15 07:51:13 +02:00
Jacek Sieka
10f0e5e9ac rm genCaseObjDiscMapping (#26097)
No longer used
2026-08-15 07:48:58 +02:00
Jacek Sieka
f489afa7e4 deprecate hotCodeReloading (#26107)
See https://github.com/nim-lang/RFCs/issues/573 - deprecating for
visibility in 2.4, in case a maintainer wants to step up - else it can
be binned for 2.6
2026-08-15 07:45:58 +02:00
ringabout
cbb3b065c7 fixes #26104; prevent compile-time-only typeof from being treated a… (#26105)
…s a runtime alias

fixes #26104

Follows up https://github.com/nim-lang/Nim/pull/25994
2026-08-14 13:36:55 +02:00
Andreas Rumpf
ebfd1c5090 fixes #26025 (#26076) 2026-08-11 22:27:49 +02:00
SirOlaf
2d22f24359 Same-module generic cache for lazy instantiation (#26091)
We defer copying the AST during generic instantiation until a cache miss
and fetch from cache based on bindings. On miss, we fall back to the old
logic and populate the cache.
This gains us a roughly 36% reduction in memory usage during bootstrap,
from `799.242MiB` down to `508.672MiB` on my machine.

For another point of reference, nimbus-eth2 goes from `10.5GB` memory
usage to `7.5GB`.

Independent companion to #26090 which together with this one yields a
bit under 20% faster compiles (or at least `--compileOnly` bootstraps)
on ORC.
2026-08-10 10:18:15 +02:00
ringabout
0ec8682abe fixes #26062; ResultUsed warning behaves inconsistently with manual c… (#26087)
…haracterization with--warning:ResultUsed:on


fixes #26062


> A return statement with no expression is shorthand for return result.

> ResultUsed: Warn about the usage of the built-in result variable.

> A procedure that does not have any return statement and does not use
the special result variable returns the value of its last expression.
2026-08-10 07:38:49 +02:00
Corey Leavitt
f4e8e04cd0 fixes #26092; restore enclosing cast block state when a nested cast block exits (#26093)
`unapplyBlockContext` reset `inEnforcedGcSafe` and
`inEnforcedNoSideEffects` to false whenever a `{.cast(gcsafe).}` or
`{.cast(noSideEffect).}` block ended. When such a block is nested inside
another block of the same cast, the inner block's exit switched
enforcement back on for the rest of the enclosing block, so statements
lexically inside the outer cast were rejected.

The fix saves both flags in `PragmaBlockContext` when the block context
is created and restores the saved values on exit. That matches how every
other piece of block state there (`locked`, `exc`, `tags`, `forbids`) is
already handled; these two bools were the only ones reset to a constant
instead of restored.

No change for non-nested blocks: entering from the non-enforced state
saves false, so exit still clears the flag. A statement after the outer
block is still rejected as before.

Test covers nested `cast(gcsafe)` and nested `cast(noSideEffect)`.
`tests/effects` passes unchanged (49/49, same as stock).
2026-08-09 11:24:02 +02:00
SirOlaf
f0e7969bb0 Miscellaneous frontend optimizations (#26090)
Boostrap without linking is (conservatively) 17% faster on my machine.

Test setup runs the compiler compiling itself under ORC in release mode
from a clean cache and no C compilation (`--compileOnly`.)
Multiple samples are gathered before judging a potential optimization.
The test suite passes locally before push and bootstrap is tested with
strict views (mostly as a sanity check).
Tests are fair in the sense that they compile the same git worktree and
produce identical C output.

Refc will see less or no benefit.


Changes:
- Save tree traversals in `considerGenSyms` when no mappings exist
- Inline `maybeSkipDistinct` into `typeRel` for a safe cursor
- Only skip to static when there is a static type to reach in
`paramTypesMatchAux`
- Disable overflow checks for hashes
- Disable bounds checks for `nextIdentIter`
- Use cursor annotation when judged safe
- Use lent annotation for ast accessors


Spiritual companion to #26084
2026-08-08 23:28:22 +02:00
ringabout
050b38c749 fixes #26036; compiler inference for sfNeverRaises (#26059)
fixes #2603

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2026-08-07 13:08:51 +02:00
Emmanuel M. Smith🔸
27763495bc lexer: add seven more unicode operators (#26074)
closes nim-lang/RFCs#571

Adds `⟑ ⟇ ⩓ ⩔ ■ □ ☆` with the same priority as `*`.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2026-08-05 16:12:17 +02:00
Jacek Sieka
c69cf36610 Simplify C file change detection (#26080)
Remove `moduleHasChanged`
2026-08-05 10:32:57 +02:00
Andreas Rumpf
0206aa334c backend: refactorings so that eventually it can run on BIF directly w… (#25959)
…ithout PNode constructions; also added bif2nif.nim inspection tool
2026-08-04 15:18:34 +02:00
nimamasl114514
1e82deb73d fix #20078: nimpretty --indent applies to keepIndents regions (#25985)
## Summary
- nimpretty with non-default \--indent\ (e.g. 3 or 10) produced invalid
indentation in if/block/try expression regions because layouter kept the
original column when \keepIndents > 0\ and ignored \indWidth\.
- Rebase the column onto \indWidth\ using the relative offset from the
enclosing block baseline (\indentStack[^1]\).

## Root cause
\parser.nim\'s \
imprettyDontTouch\ template sets \keepIndents\ for if/block/try
expressions. layouter in the \keepIndents > 0\ branch used \ ok.indent\
(source column) directly as \indentLevel\ without scaling by \indWidth\,
so lines in these regions kept the original column and misaligned with
the rest of the file when \--indent\ differed from source indent width.

## Fix
\\\
im
em.indentLevel = em.indentStack.high * em.indWidth +
                 (tok.indent - em.indentStack[^1])
\\\

Keeps the relative offset from the enclosing block baseline but rebases
onto \indWidth\. At default \--indent:2\ the offset equals \indWidth\,
so output is unchanged (backwards compatible).

## Testing
- 12 custom cases x 3 indent values (2/3/10) = 36/36 pass
- nimpretty self-test suite 7/7 pass (no regression at default indent)
- 5 keepIndents scenarios (if/block/try expression continuation
alignment) that failed at indent:3/10 now pass

Fixes #20078.
2026-08-03 12:15:44 +02:00
ringabout
23365deef0 fixes #26023; incorrect sink requires a copy (#26028)
fixes #26023
2026-08-03 12:02:29 +02:00
ringabout
234f01510f fixes #25942 #25938; type inference for static container type (#25989)
fixes #25942 
fixes #25938

After a successful match to a concrete static T, normalizes an empty
static container literal to the formal payload type before binding it.
This prevents `static[set[empty]]({})` from leaking into the
instantiated proc body.
2026-08-03 11:52:04 +02:00
Ryan McConnell
5137d273e5 fix #25993; In-place object construction zeroes destination before evaluating self-referencing field values (#25994) 2026-08-03 11:51:16 +02:00
ringabout
f6651e6c70 fixes #26045; #26046; when nimvm leak push options (#26047)
fixes #26045; 
fixes #26046

The fix isolates compiler option state while semantically checking each
when nimvm branch.

compiler/semexprs.nim:2745 snapshots the option stack, compiler options,
diagnostics settings, and enabled features. It analyzes one branch and
restores that state in finally. Both the nimvm and else branches use
this function.

This prevents:

```nim
when nimvm:
  {.push overflowChecks: off.}
```

from disabling overflow checks in following runtime code. It also means
a {.pop.} in the opposite branch correctly reports that it has no
corresponding {.push.}.
2026-08-03 11:49:48 +02:00
Andreas Rumpf
3126a47590 YRC: optimizations (#26042) 2026-07-30 14:54:12 +02:00
Ryan McConnell
2d81149294 unwrap typedesc in semSet to enable stuff like set[T.distinctBase] (#25924)
`distinctBase` results in typedesc, so `set[T.distinctBase]` received
`typedesc[range[...]]` as its element type, which `isOrdinalType`
rejects. Strip the wrapper in `semSet` before storing the element type
and checking ordinality.

Also add `tyFromExpr` to the deferred-check set so the error doesn't
fire prematurely inside generic bodies - same pattern already used by
`semArray`.
2026-07-26 18:08:44 +02:00
ringabout
99a696e0c4 fixes #26010; Double destroy with {.cursor.} (#26031)
fixes #26010

Cursors do not own their values and therefore cannot transfer ownership
through move.
Reject move(cursor) during semantic analysis and share the
cursor-location check
between semantic analysis and destructor injection.
2026-07-24 14:07:15 +02:00
cryo2010
8e8f8de1ab fix: exception leak in closure iterator typed except branches (#23615) (#26034)
Fixes #23615

## Root cause

The leak does not require async at all -- this minimal closure iterator
leaks the exception and its stacktrace seq under ARC/ORC:

```nim
iterator it(): int {.closure.} =
  try:
    yield 1                              # try spanning a yield => closureiters transform
    raise newException(ValueError, "x")
  except ValueError:                     # typed except => generated `of` check
    discard
  yield 2
```

A bare `except:` does not leak; a *typed* `except` does:

1. `collectExceptState` in `compiler/closureiters.nim` generates the
except-branch type check as `of(getCurrentException(), T)`, using the
raw generic magic sym from `getSysMagic("of", mOf)`.
2. `injectdestructors` skips call arguments whose *formal* parameter
type is `isCompileTimeOnly`, and the raw generic `of` sym's formal
params are `tyGenericParam` so both arguments of the generated `of` call
are never processed.
3. `getCurrentException()` increfs `currException` via `=copy` into its
result. Since the arc pass never wraps that owned temp in a destroy
(`--expandArc` shows the condition left untouched, while a user-written
`if f() of ValueError` in the same iterator gets a `:tmpD` +
`=destroy`), the caught exception's refcount stays +1 forever.

Every `try: await x() except SomeError` in async code has this shape, so
each caught async exception leaked once.

## Fix

The state-machine wrapper already stores the active exception in the
`:curExc` env field before jumping to the except landing state, and
`currException == :curExc` on every path into that state. The generated
condition now references the env field via `ctx.newCurExcAccess()`
instead of calling `getCurrentException()` again -- no ownership
transfer, no temp to destroy, one fewer runtime call.

Note: the underlying `injectdestructors` behavior (skipping args of
calls whose formal params are raw `tyGenericParam`, e.g. from
`getSysMagic`) is a separate latent gap that could affect other
compiler-generated code; it is intentionally left untouched here.

## Valgrind, before and after

Exact code and command from the issue, on Linux (Valgrind 3.19):

```
nim c -d:danger --mm:orc --debugger:native --threads:off -d:useMalloc bug.nim
valgrind --leak-check=full --show-leak-kinds=all ./bug
```

Before (devel):

```
==14663== HEAP SUMMARY:
==14663==     in use at exit: 136 bytes in 2 blocks
==14663==   total heap usage: 22 allocs, 20 frees, 116,466 bytes allocated
==14663==
==14663== 56 bytes in 1 blocks are indirectly lost in loss record 1 of 2
==14663==    at 0x488A1C4: realloc (vg_replace_malloc.c:1437)
==14663==    by 0x10C663: prepareSeqAddUninit (seqs_v2.nim:212)
==14663==    by 0x10CF6F: raiseExceptionEx (excpt.nim:538)
==14663==    by 0x11661F: amain::amainX20X28AsyncX29_(Future<void>) (bug.nim:10)
==14663==    ...
==14663==
==14663== 136 (80 direct, 56 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==14663==    at 0x48850C8: malloc (vg_replace_malloc.c:381)
==14663==    by 0x10C8E3: nimNewObj (arc.nim:122)
==14663==    by 0x115403: err::errX20X28AsyncX29_(Future<void>) (asyncmacro.nim:274)
==14663==    by 0x116027: err::errNimAsyncContinue(Future<void>, ClosureIt<void>) (asyncmacro.nim:44)
==14663==    by 0x1163D3: bug::err (bug.nim:3)
==14663==    ...
==14663==
==14663== LEAK SUMMARY:
==14663==    definitely lost: 80 bytes in 1 blocks
==14663==    indirectly lost: 56 bytes in 1 blocks
==14663==      possibly lost: 0 bytes in 0 blocks
==14663==    still reachable: 0 bytes in 0 blocks
==14663== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```

After (this PR):

```
==14675== HEAP SUMMARY:
==14675==     in use at exit: 0 bytes in 0 blocks
==14675==   total heap usage: 22 allocs, 22 frees, 116,466 bytes allocated
==14675==
==14675== All heap blocks were freed -- no leaks are possible
==14675==
==14675== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```

## Testing

- New `tests/async/t23615.nim` (modeled on `t23212.nim`: `valgrind:
true` + alloc-stats assertion) covers both the pure closure-iterator
form and the async form from the issue, with the caught exception looped
50x so the leak blows well past the slack threshold. It passes with this
PR and fails against devel.
- Testament categories `async`, `arc`, `iter`, `exception` all pass with
the patched compiler (323 tests).
- Behavior is unchanged on a sanity program covering multi-branch
dispatch, `as e` binding, nested try, and re-raise across yields: output
is byte-identical to devel; the patched build just frees 2 more blocks
per caught exception.
2026-07-24 14:06:27 +02:00
Andreas Rumpf
cd3e9a46b2 run async tests under --mm:yrc (#26033) 2026-07-24 14:04:45 +02:00
ringabout
0cf1bc3835 fixes #26019; deepCopy should not be allowed for non-copyable type (#26030)
fixes #26019
2026-07-22 12:36:48 +02:00
Jaremy Creechley
adda34bcb8 add --genBif for semantic BIF output on non-IC builds (#26001)
## Summary

Adds `--genBif:on|off`, allowing regular compiler builds to generate
per-module semantic BIF artifacts in `nimcache`.

This reuses the semantic artifact format produced by incremental
compilation without enabling IC or changing the normal code-generation
and linking pipeline.

In comparison to `nim check --compress ...` this new flag `nim c
--genBif:on --compileOnly yourlib.nim` is considerably more useful for
tooling.

That produced full semantic proc declarations, Nim visibility,
signatures, overload disambiguators, and pragmas. For a proc that was
actually code-generated, it also recorded the exact backend name, for
example.

## Motivation

External tools such as language servers, debuggers, and binding
generators can benefit from resolved symbol and type information
produced during an ordinary build. Previously, these semantic BIF
artifacts were tied to the incremental compiler workflow.

## Details

With the option enabled:

```sh
nim c --genBif:on project.nim
```

the compiler writes semantic `.s.bif` files and their supporting
sidecars for each semantically checked module while continuing with the
requested backend normally.

The option:

- Works with non-IC builds.
- Does not enable incremental compilation.
- Does not change generated program behavior.
- Does not enable or introduce native ABI exports.
- Does not generate `.abi.nif` manifests.
- Is ignored for NimScript compilation.

The `genBif` name follows existing artifact-generation options such as
`genScript`, `genMapping`, and `genCDeps`.

## Testing

Added a focused C backend test that runs a regular build with
`--genBif:on` and verifies that semantic `.s.bif` artifacts are
generated.

A release-mode temporary compiler build and the focused Testament test
both pass.
2026-07-20 13:01:30 +02:00
ringabout
2915691515 fixes #26000; Cannot add members to enum-indexed array of seqs at com… (#26013)
…pile time

fixes #26000


vm: preserve lvalues for mutations of broadcast array elements

Load in-place mutation targets through their address so mutations don't
operate on detached copies of broadcast defaults. This also preserves
nested lvalues and evaluates indexed destinations only once.

Cover sequence, string, and set mutations through direct, nested, field,
enum-indexed, and range-indexed array elements.
2026-07-20 12:59:18 +02:00
Andreas Rumpf
fa66510f7a IC: bugfix (#25982) 2026-07-10 14:07:35 +02:00
ringabout
4b1444e728 fix #25976: treat proc-type forbids as an empty tag set (#25980)
fix #25976

Initialize tagEffects for proc types that declare .forbids but omit
.tags,
so they behave like explicit tags: [] during indirect-call effect
tracking.
Add a regression for the nested callback assignment case.
2026-07-10 07:39:32 +02:00
Andreas Rumpf
1dc079b723 nim-track: make include files work (#25977) 2026-07-09 22:13:39 +02:00
Mamy Ratsimbazafy
e50fafc971 Fix #25883 tuple sighash collision (#25889)
fixes #25886
fixes #25883

See #25883 

Tuples only hash leaves so if 2 tuples have the same flattened
representation they collide in the C codegen.

Fix by hashing the length as well to disambiguate nesting levels.

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2026-07-09 15:47:58 +02:00
Andreas Rumpf
b290be8d83 nim-track: dedup outputs; make --defusages work (#25975) 2026-07-09 10:16:30 +02:00
Andreas Rumpf
ccc2372884 nim-track: bugfixes (#25974) 2026-07-09 00:20:57 +02:00
Andreas Rumpf
f5cf44d7d5 nim track: oneshot nimsuggest (#25971) 2026-07-08 15:39:40 +02:00
ringabout
c70a4502d2 fix #25608; improve implicit range conversion checks (#25838)
fix #25608

This pull request improves how the compiler handles warnings for
implicit range conversions, ensuring that only non-constant values
trigger downsizing warnings. It also adds new test cases to verify that
assignments and function calls involving compile-time constants do not
produce unnecessary warnings.

Improvements to range conversion warnings:

* Updated the logic in `compiler/sempass2.nim` to skip implicit range
conversion warnings for compile-time constants by checking if an
expression is constant with `getConstExpr`. Now, only non-constant
values will trigger the warning.

Testing enhancements:

* Added new test cases in `tests/range/timplicitrangedownsizing.nim` to
confirm that assignments and function calls with constant enum and
integer values do not trigger downsizing warnings.
2026-07-06 14:26:14 +02:00
Andreas Rumpf
0bfb59f6d4 IC: final tweaks (#25958) 2026-07-04 10:13:39 +02:00