Commit Graph

8744 Commits

Author SHA1 Message Date
narimiran
7fef8700e0 Revert "fixes #25992; fix GC tracing of stale bytes in case objects during reset (#26003)"
This reverts commit 84a5613c35.
2026-08-28 16:38:07 +02:00
Zoom
a36bfd4977 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.

(cherry picked from commit bd95f88f74)
2026-08-28 16:34:21 +02:00
ringabout
2479311fcb 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>
(cherry picked from commit dc242e9027)
2026-08-28 16:34:13 +02:00
ringabout
85ce118386 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

(cherry picked from commit f1256ddcf4)
2026-08-28 16:31:55 +02:00
ringabout
af0363efe6 fix #26112: update variable kinds in isPartOf to include skResult (#26114)
fix #26112

(cherry picked from commit 1201c184d7)
2026-08-28 16:31:34 +02:00
ringabout
84a5613c35 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.

(cherry picked from commit 16920b56d1)
2026-08-28 16:30:23 +02:00
Jacek Sieka
1cdcace755 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

(cherry picked from commit f489afa7e4)
2026-08-28 16:25:53 +02:00
Jacek Sieka
34923f683c rm cherry-pick cruft (#26098)
`astdef.nim` should not exist in 2.2
2026-08-15 07:50:23 +02:00
Andreas Rumpf
13f4ed0d70 fixes #26025 (#26076)
(cherry picked from commit ebfd1c5090)
2026-08-12 09:14:58 +02:00
narimiran
235bfc3a3b fix broken code 2026-08-10 09:46:56 +02:00
ringabout
4ce3d87c7e 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.

(cherry picked from commit 0ec8682abe)
2026-08-10 08:12:26 +02:00
Corey Leavitt
445d46dd9e 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).

(cherry picked from commit f4e8e04cd0)
2026-08-10 08:11:59 +02:00
ringabout
953466839e fixes #26036; compiler inference for sfNeverRaises (#26059)
fixes #26036

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit 050b38c749)
2026-08-10 08:09:52 +02:00
nimamasl114514
db6d61b387 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.

(cherry picked from commit 1e82deb73d)
2026-08-06 09:19:30 +02:00
ringabout
21fe5f423f fixes #26023; incorrect sink requires a copy (#26028)
fixes #26023

(cherry picked from commit 23365deef0)
2026-08-06 09:19:22 +02:00
ringabout
a2cf8e0ced 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.

(cherry picked from commit 234f01510f)
2026-08-06 09:18:57 +02:00
ringabout
8a411da772 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.}.

(cherry picked from commit f6651e6c70)
2026-08-06 09:18:45 +02:00
Ryan McConnell
6821206115 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`.

(cherry picked from commit 2d81149294)
2026-08-06 09:17:58 +02:00
ringabout
9cfc5cfbeb 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.

(cherry picked from commit 99a696e0c4)
2026-08-06 09:16:19 +02:00
cryo2010
7fe9cf92ad 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.

(cherry picked from commit 8e8f8de1ab)
2026-08-06 09:15:11 +02:00
ringabout
25e3f6a23a fixes #26019; deepCopy should not be allowed for non-copyable type (#26030)
fixes #26019

(cherry picked from commit 0cf1bc3835)
2026-08-06 09:14:45 +02:00
ringabout
9d4970cf71 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.

(cherry picked from commit 2915691515)
2026-08-06 09:11:44 +02:00
ringabout
eca3741f76 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.

(cherry picked from commit 4b1444e728)
2026-07-18 10:23:03 +02:00
Mamy Ratsimbazafy
5c1fdc90b6 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>
(cherry picked from commit e50fafc971)
2026-07-18 10:22:47 +02:00
ringabout
f0706b2026 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.

(cherry picked from commit c70a4502d2)
2026-07-08 20:59:11 +02:00
Savant
2c3a728c4f js: cursor inference to elide nimCopy for safe value aliases (#25948)
(cherry picked from commit c7ea004ca9)
2026-07-06 08:44:50 +02:00
ringabout
df0eedcbf3 fixes genMagicExpr: handle mAsgn for Isolated[T] with primitive types in tuple assignment (#25955)
Explicit `=sink` calls such as `Isolated[T].=sink` can delegate to a
field type like `float`, which has no attached sink op. In that case
`replaceHookMagic` leaves the builtin `mAsgn` call in place.
`genMagicExpr` did not lower that shape, which caused the regression.
Mapping `=sink` to `nkSinkAsgn` and other builtin assignment hooks to
`nkAsgn`.

(cherry picked from commit 985b1125b1)
2026-07-06 08:44:41 +02:00
ringabout
86bbafe1a7 fixes #25945; cannot map the empty seq type to a C type (#25954)
fixes #25945

When `@[]` appears inside a nested `if` expression that also contains
statements, the AST wraps it in `nkStmtListExpr` nodes. The empty
container's `tyEmpty` element type was never resolved to a concrete
type, causing the C codegen to ICE with "cannot map the empty seq type
to a C type".

Walk through nested statement-list/block expressions in
`fitNodePostMatch` to find the innermost value node and propagate the
formal type to empty containers.

(cherry picked from commit a0e44d7aca)
2026-07-06 08:42:41 +02:00
ringabout
0b7f9e95e6 Improve effect propagation by skipping hooks in trackCall (#25940)
ref https://github.com/nim-lang/Nim/pull/25731
don't propagate effects for assignment hooks without effect lists

(cherry picked from commit 6828effd13)
2026-06-30 13:31:37 +02:00
ringabout
115b0a1dae fixes #25931; type N {.importc: "const void *".} = pointer creates order-dependent compilation failure (#25936)
fixes #25931

This fix addresses bug #25931 — a signature hash collision with
importc-aliased pointer/cstring types.
The problem: In compiler/sighashes.nim, the hashType procedure
canonicalizes types for signature hashing. Integral types
(tyInt..tyUInt64, etc.) were excluded from canonicalization so that
types like pid_t (an importc alias) keep their backend spelling. But
pointer and cstring types with importc annotations were not excluded —
meaning a type like:
type N {.importc: "const void *".} = pointer
...would be collapsed to just pointer in the signature hash, causing
collisions when N and pointer are both used in procedure types within
the same compilation unit.
The fix (compiler/sighashes.nim:193): Adds tyPointer and tyCstring to
the list of types that skip canonicalization, right alongside the
integral types. The comment is updated to clarify this applies to
"builtin scalar-ish / pointer-like types".
The test (tests/ccgbugs/tsighash_typename_regression.nim:33-42): Adds a
regression test exercising the exact scenario — an importc pointer alias
used in both an object field type and a proc parameter type.

(cherry picked from commit 056eeeae30)
2026-06-25 19:59:03 +02:00
ringabout
f314df4efe fixes #25908; resolves lent enum disambiguation (#25929)
fixes #25908

When an enum identifier is resolved as an `nkSymChoice`, one of the
candidates may come from a loop-local view and carry `tyVar` or
`tyLent`.

Enum disambiguation should compare the underlying enum type only.
Otherwise a pure-enum field can win incorrectly even though the intended
symbol is already present in the choice set.

Keep the `includePureEnum` lookup path for enum-typed expectations so
#23976 still works, but normalize `var`/`lent` only at the symchoice
selection point.

(cherry picked from commit 6eef0cc2d5)
2026-06-24 09:23:48 +02:00
Ryan McConnell
13ab5c5d23 fix: {.cast(uncheckedAssign).} ineffective across yield in closure iterators (#25916)
closureiters.nim splits a stmt list at yield points, moving post-yield
code into a new state body. When that stmt list was inside a pragma
block like `{.cast(uncheckedAssign).}`, the new state's body was created
as a bare nkStmtList without the wrapper.

Fix: track the enclosing pragma block in the transform context, and wrap
newly-created state bodies in a copy of it when the split occurs inside
one. Added an explicit `nkPragmaBlock` case to
`transformClosureIteratorBody` that saves/restores `ctx.enclosingPragma`
around its body.

(cherry picked from commit f8e470eb57)
2026-06-24 09:23:40 +02:00
ringabout
90eb2e2c1b fixes #22122; Unclear error message for raise of a complex expression (#25899)
fixes  #22122

The commit fixes a bug in Nim's effects checker where raise statements
with case/if expressions (commonly from template expansion) failed to
track exception types from individual branches.
Problem: addRaiseEffect only saw the outermost expression. When a
template like getTransportError(err) expanded to a case expression
raising 3 different exception types, the compiler only registered the
top-level call — missing the branch-level exceptions.
Fix (2 files):
- compiler/sempass2.nim: Added skipHiddenConv to strip implicit type
coercion nodes (nkHiddenStdConv/nkHiddenSubConv) that hide the control
flow structure. Added addRaiseEffectsFromExpr that recursively walks
into case/if/block/stmtlist expressions to find raise effects in each
branch body. Changed the nkRaiseStmt handler to use this new function.
- tests/effects/tcase_raises.nim: Test with templates that expand to
case expressions raising different exception types, verified via
{.raises: [].} pragma.

(cherry picked from commit 587f90a816)
2026-06-15 08:01:32 +02:00
ringabout
40d40039d3 fixes #25885; incompleteStruct ignored without importc (#25898)
fixes #25885

(cherry picked from commit 8ad1d106ec)
2026-06-15 08:01:21 +02:00
ringabout
cad29b1fa6 fixes #18367 and #21222; using quote inside static block (#25907)
fixes #18367
fixes #21222

1. In vmdef.nim:304, newCtx now sets templInstCounter: new int when it
builds TCtx.
2. vm.nim:1490 — During VM execution of templates, c.templInstCounter is
passed to evalTemplate
3. evaltempl.nim:204 — instID: instID[] dereferences the ref int
4. With a nil templInstCounter, this would crash
5. The same initialization already exists on the semantic side in
sem.nim:787, so this change makes the VM path consistent with the rest
of the compiler.

(cherry picked from commit 67707a54b5)
2026-06-15 08:01:11 +02:00
ringabout
5fc6a3881a fixes #25903 and #25904; add closure iterators with error handling (#25905)
fixes #25903
fixes #25904

`nkExceptBranch` can have variable structure depending on the exception
types and it should handle the last node of the `nkExceptBranch`

(cherry picked from commit 0f751695e4)
2026-06-15 08:01:00 +02:00
WyattBlue
bf3e0ca379 adds wasm64 (Memory64) as a first-class target (#25900)
This pull request allows setting `--cpu:wasm64`, allowing wasm64 as a
first class target. This avoids having to set `-cpu:riscv64` as a
workaround. Sane defaults for the emscripten toolchain are also
provided.

(cherry picked from commit b44d373b7d)
2026-06-12 10:27:15 +02:00
Jacek Sieka
ffeafeab74 fix state array constant types (#25893)
else there's a mismatch in the AST for the bracket constructor

(cherry picked from commit 13d152a4d1)
2026-06-12 10:26:45 +02:00
Jacek Sieka
3f48ce8009 astyaml: formatting fixes (#25897)
fix missing indent and newlines here and there

(cherry picked from commit c620adcfce)
2026-06-12 10:26:34 +02:00
Ryan McConnell
2d30ebaea9 fix 25778; concept coerces incompatible types (#25781)
I don't like it, but seems like this is correct. Concept type classes
have to behave like other "named" type classes and participate in "bind
once" mechanics or require some weird semantics. As a side note I'm
pretty sure the `tuple` example in the manual explaining this is either
wrong now or has regressed, but I don't think it matters because I doubt
anyone thinks about this feature much.
#25778

(cherry picked from commit 0448557bfe)
2026-06-12 10:26:17 +02:00
Tomohiro
db595b397c adds modifierMode parameter to typeof (#25815)
This PR adds 3 modes to `typeof` to specify how to handle type modifiers
`var`, `sink` and `lent`.

- typeOfModCompatible
Remove or keep type modifiers in the same way as old typeof. That means
keep `sink` but remove `var` and `lent`.
- typeOfModRemoveModifier
  Remove type modifiers.
- typeOfModKeepModifier
  Keep type modifiers.

Related to https://github.com/nim-lang/Nim/pull/25779
https://github.com/nim-lang/Nim/issues/25786

(cherry picked from commit 48621c217f)
2026-06-12 10:25:10 +02:00
narimiran
848188512c Revert "fixes #22122; raise effects for complex expressions (#25845)"
This reverts commit 2c6191aa4d.
2026-06-09 09:59:29 +02:00
ringabout
2c6191aa4d fixes #22122; raise effects for complex expressions (#25845)
fixes #22122

The root cause is in the effect tracker: raise was recording the whole
conditional expression as one exception source, so semantic checking
only saw the widened common base type instead of the concrete exception
classes from each branch.

(cherry picked from commit e942da94b5)
2026-06-09 06:25:17 +02:00
Andreas Rumpf
8c02426855 fixes #25693; continues the bugfix story (#25876)
(cherry picked from commit 7a5e35c83e)
2026-06-09 06:24:20 +02:00
ringabout
e757c5ec26 fixes #25725; environment misses: s with iterator (#25828)
fixes #25725

This pull request makes significant improvements to symbol handling
during transformation passes in the compiler, particularly for routines
(procedures, iterators) and their parameters. The changes ensure that
when routines are copied (for inlining, closure generation, etc.), all
relevant symbols and type headers are also freshly copied and correctly
owned, preventing subtle bugs from symbol reuse. Additionally, new
regression tests are added to cover previously problematic iterator
cases.

**Improvements to symbol copying and ownership:**

* Introduced `freshOwnedSym` to create a fresh copy of a symbol with a
specified owner, ensuring that transformed routines and their parameters
do not share symbols with the originals, which prevents accidental
aliasing and ownership issues.
* Refactored `freshVar` to use `freshOwnedSym`, centralizing fresh
symbol creation logic.
* Added `introduceNewRoutineHeaderSyms` and `copyRoutineTypeHeader` to
ensure that when routines are copied, all parameter/result symbols and
their types are also freshly copied and mapped, avoiding shared state
between original and transformed routines.
* Updated `introduceNewLocalVars` to use `freshOwnedSym` for routine
symbols and to invoke the new header/type copying procedures, ensuring
correctness in routine transformation.

**Testing and regression coverage:**

* Added new blocks to `tests/iter/titer_issues.nim` to test iterator
transformation edge cases, including scenarios that previously led to
symbol reuse bugs (e.g., bugs #25724 and #25725).

(cherry picked from commit f959a02037)
2026-06-08 14:50:54 +02:00
ringabout
917f5bb6ff fixes #22936; Generic inheritance matching gives type mismatch when object has members (#25836)
fixes #22936

This pull request improves the compiler's handling of generic type
constraints, specifically for subtypes of generics, and adds a test to
cover this behavior. The main changes are an enhancement to the type
relationship logic in the compiler and a new test case for generic
subtyping with `Future`.

### Compiler improvements for generic subtyping

* Updated `typeRel` in `compiler/sigmatch.nim` to allow generic
constraints (like `F: Future`) to accept not just direct instantiations
but also descendants of the generic family, ensuring more flexible and
correct overload resolution. Inheritance depth is now considered for
overload ranking, making deeper descendants slightly less preferred,
consistent with other inheritance-based matches.

### New test coverage

* Added a test in `tests/typerel/t8905.nim` to verify that generic
constraints correctly accept subtypes of `Future`, including a custom
`B[T, E] = ref object of Future[T]` type, and that overloads like
`take`, `takeMany`, and the macro `checkFutures` work as expected with
these types.

(cherry picked from commit 1d7510dff0)
2026-06-08 14:48:53 +02:00
Tomohiro
72b5e904b9 fixes-25655; defining >= operator generates compile error (#25787)
Fixes https://github.com/nim-lang/Nim/issues/25655

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
(cherry picked from commit 9b80b2e868)
2026-06-08 14:48:42 +02:00
ringabout
ccfdfff550 fixes #20811; Nested proc with inner being generic cannot access parameters of outer proc (#25837)
fixes  #20811

This pull request addresses issues with parameter capture in nested
generic procedures and templates, ensuring that outer parameters are
correctly visible and accessible within nested scopes. The main changes
include a fix in the semantic analysis logic and the addition of
targeted regression tests.

### Semantic analysis improvements:
* Updated `semGenericStmtSymbol` in `compiler/semgnrc.nim` to ensure
that parameters from outer scopes are preserved and accessible in nested
generic procedures, fixing visibility issues with captured parameters.

### Added regression tests:
* Added `tests/generics/t20811.nim` to verify that both generic and
plain inner procedures can access parameters from their enclosing
procedure.
* Extended `tests/template/topensym.nim` with a new block for issue
#20811 to test that template-injected parameters are correctly captured
and visible in nested generic procedures.

(cherry picked from commit f5930d0bb3)
2026-06-08 14:48:32 +02:00
ringabout
f3f7b2b516 fixes #18238; Nested object construction can zero same memory multiple times for --mm:refc (#25834)
fixes #18238

This pull request makes a targeted change to the object construction
logic in the `genObjConstr` procedure. The main update refines the
conditions under which memory zeroing is required during object
construction, making the behavior more accurate for different garbage
collection and destructor options.

Key logic update:

- Improved the `needsZeroMem` condition in `genObjConstr` to check for
the presence of garbage-collected references and the `optSeqDestructors`
option, instead of relying solely on the selected garbage collector and
field flags. This ensures memory is zeroed only when necessary,
potentially improving performance and correctness.

```c
T1_ = NIM_NIL;
T1_ = ((tyObject_E__uEKympBdEK4SY9anUbpNaLQ*) newObj((&NTIrefe__bJ9cSuxv8xHYxmdolQqFkUw_), sizeof(tyObject_E__uEKympBdEK4SY9anUbpNaLQ)));
nimZeroMem(((void*) ((&(*T1_).z.z.z.z))), sizeof(tyObject_A__G2lWlL9cFqoiWWwZmWqfJ9bA));
(*T1_).z.z.z.z.y = ((NI) 5);
asgnRef(((void**) ((&z1__test8_u12))), T1_);
asgnRef(((void**) ((&z2__test8_u55))), new__test8_u13());
(*z2__test8_u55).z.z.z.z.y = ((NI) 5);
T2_ = NIM_NIL;
T2_ = ((tyObject_E__uEKympBdEK4SY9anUbpNaLQ*) newObj((&NTIrefe__bJ9cSuxv8xHYxmdolQqFkUw_), sizeof(tyObject_E__uEKympBdEK4SY9anUbpNaLQ)));
asgnRef(((void**) ((&z3__test8_u56))), T2_);
(*z3__test8_u56).z.z.z.z.y = ((NI) 5);
```

The original test case has already been fixed for `ORC`, now extends it
to `refc`: if a constructor is fully initialized, it does not need a
zero-fill step

(cherry picked from commit 4497d89267)
2026-06-08 14:48:12 +02:00
Andreas Rumpf
0c4d564e7b fixes #25850 (#25875)
(cherry picked from commit 3c6449dbdd)
2026-06-08 08:49:11 +02:00