Commit Graph

6857 Commits

Author SHA1 Message Date
metagn
6f85d348f4 fix @ for openarray on nimscript [backport:2.2] (#25641)
Even on nimscript, the `else` branch of the `when nimvm` below compiles
and gives an "undeclared identifier: copyMem" error. Regression since
#25064.
2026-03-24 08:27:28 +01:00
ringabout
c48f487780 fixes: replace ensureMutable with backendEnsureMutable in ccgtypes (#25640) 2026-03-24 11:49:06 +08:00
ringabout
8bb63b475b fixes global tuple unpacking for nim ic (#25624)
This pull request includes a few targeted changes across the codebase,
primarily focusing on improving symbol locality detection in the
compiler, adding a utility function for integer division and modulus,
and simplifying a test case.

- **Compiler Improvements**
* Improved the `isLocalSym` function in `compiler/ast2nif.nim` to more
accurately determine if a symbol is local by checking that the symbol's
owner is not a module.

- **Utility Function Addition**
* Added a new `divmod` procedure in `tests/ic/tmiscs.nim` that returns
both the quotient and remainder of integer division, along with a usage
example.

- **Test Simplification**
* Simplified the `showMeters` test in `tests/ic/tconverter.nim` by
removing a floating-point assertion, leaving only an output statement.



------------------------------------------------------------------------------------------------------------------

```nim
proc divmod(a, b: int): (int, int) =
  (a div b, a mod b)


let (q, r) = divmod(17, 5)
echo q
echo r
```

gives `Error: unhandled exception: local symbol 'tmpTuple.0' not found
in localSyms. [AssertionDefect]`

`makeVarTupleSection` uses a temp of which the globalness and localness
is not specified. Turning it a global variable for top level scope broke
some Nim programs. So I think it's better to check the owner of the
symbol

```nim
if useTemp:
  # use same symkind for compatibility with original section
  let temp = newSym(symkind, getIdent(c.cache, "tmpTuple"), c.idgen, getCurrOwner(c), n.info)
```
2026-03-23 09:35:30 +01:00
ringabout
a4a482b5ef fixes #25620; typekey skips incorrectly the base type of seqs etc. types for nim ic (#25621)
fixes #25620

This pull request includes a fix to the type key generation logic in the
compiler and updates to a test file to cover additional language
features. The most important changes are summarized below:

### Compiler logic fix

* In `compiler/typekeys.nim`, the `typeKey` procedure was updated to
iterate over all elements in `t.sonsImpl` starting from index 0 instead
of 1, ensuring that all type sons are considered during type key
generation.

### Test suite improvements

* The test file `tests/ic/tenum.nim` was renamed to
`tests/ic/tmiscs.nim`, and its output expectations were updated to
reflect the new test cases.
* Added new test cases to `tests/ic/tmiscs.nim` to cover sink and move
semantics, including the definition of a `BigObj` type and a `consume`
procedure that demonstrates moving and consuming large objects.

```nim
# Sink and move semantics
type
  BigObj = object
    data: seq[int]

proc consume(x: sink BigObj) =
  echo x.data.len

var b = BigObj(data: @[1, 2, 3, 4, 5])
consume(move b)
```

gives

```
error: passing 'tySequence__qwqHTkRvwhrRyENtudHQ7g' (aka 'struct tySequence__qwqHTkRvwhrRyENtudHQ7g') to parameter of incompatible type 'tySequence__cTyVHeHOWk5jStsToosJ8Q' (aka 'struct tySequence__cTyVHeHOWk5jStsToosJ8Q')
   84 |         eqdestroy___sysma2dyk_u75((*dest_p0).data);
```

follows up https://github.com/nim-lang/Nim/pull/25614
2026-03-20 07:07:26 +01:00
ringabout
197633dc8b fixes empty tag for nim ic (#25615)
`writeNode` writes `(empty flags type (empty))`, but it should have been
`(empty flags type)` instead

```nim
type
  Meters = distinct float
  Feet = distinct float

converter toMeters(f: Feet): Meters =
  Meters(float(f) * 0.3048)

proc showMeters(m: Meters) =
  echo float(m)

showMeters(Feet(10.0))
```
gives `[NIF decoder] expected: {ParRi} but got:
ParLe14,152,/Users/blue/.choosenim/toolchains/nim-\23devel/lib/std/private/dragonbox.nim(empty)`

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 07:36:09 +01:00
ringabout
a7e0065056 implements EnumToStrEntry for nim ic (#25614)
```nim
type
  NodeKind = enum
    nkInt, nkStr, nkAdd

  Node = object
    case kind: NodeKind
    of nkInt: intVal: int
    of nkStr: strVal: string
    of nkAdd: left, right: ref Node

proc newInt(v: int): ref Node =
  new(result)
  result[] = Node(kind: nkInt, intVal: v)

let n = newInt(42)
echo n.intVal
```

gives `unhandled exception: key not found: (module: 68, item: 3)
[KeyError]`
2026-03-19 07:35:24 +01:00
Andreas Rumpf
d0919b6df8 fixes #25596 (#25609) 2026-03-16 16:56:18 +01:00
Jake Leahy
edbb32e4c4 Fix getTypeImpl not returning defaults (#25592)
`getTypeImpl` and friends were always putting `nkEmpty` in the default
value field which meant the default values couldn't be introspected.
This copies the default AST so it can be seen in the returned object
2026-03-09 11:59:12 +01:00
metagn
7a87e7d199 fix compiler crash with uncheckedAssign and range/distinct discrims [backport] (#25585)
On simple code like:

```nim
type Foo = object
  case x: range[0..7]
  of 0..2:
    a: string
  else:
    b: string

var foo = Foo()
{.cast(uncheckedAssign).}:
  foo.x = 5
```

The compiler tries to generate a destructor for the variant fields by
checking if the discrim is equal to the old one, but the type is not
skipped when looking for an `==` operator in system, so any
discriminator with type `range`/`distinct`/etc crashes with:

```
(10, 9) Error: can't find magic equals operator for type kind tyRange
```

This is fixed by just skipping abstract types.
2026-03-07 07:39:57 +01:00
ringabout
e4b1d8eebc fix #25508; ignores void types in the backends (#25550)
fix #25508
2026-03-05 23:08:51 +01:00
ringabout
8e2547a5e2 fixes #25566; {.align.} pragma where each 16-byte-aligned (#25570)
fixes #25566
2026-03-04 09:14:13 +01:00
Ryan McConnell
46cddbccd6 fixes #25572 ICE evaluating closure iter with object conversion (#25575) 2026-03-04 05:45:16 +01:00
ringabout
bd709f9b4c fixes #25262; proc v[T: typedesc]() = discard / v[0]() compiles even though 0 isn't a typedesc (#25558)
fixes #25262

```nim
if constraint != nil and constraint.kind == tyTypeDesc:
  n[i].typ = e.typ
else:
  n[i].typ = e.typ.skipTypes({tyTypeDesc})
```
at least when `constraint` is a typedesc, it should not skip
`tyTypeDesc`


```nim
if arg.kind != tyTypeDesc:
  arg = makeTypeDesc(m.c, arg)
```
Wrappers literals into typedesc, which can cause problems. Though, it
doesn't seem to be necessary
2026-02-28 23:01:09 +01:00
ringabout
4566ffaca9 fixes #25553; Invalid codegen for accessing tuple in array (#25555)
fixes #25553
2026-02-28 22:51:38 +01:00
Raka Hourianto
9b2b286baf nre: fix replacement string parser OOB access, numeric refs, and unterminated named refs (#25560)
1. A trailing `$` at the end of a replacement string could read out of
bounds via `how[i + 1]`; this now raises `ValueError` instead.

2. Numeric capture parsing used `id += (id * 10) + digit` instead of `id
= (id * 10) + digit`, so multi-digit refs were parsed incorrectly (e.g.
`$12` resolved as capture 13 instead of 12).

4. Unterminated named replacement syntax (e.g. `${foo)` is now rejected
with ValueError instead of being accepted and parsed inconsistently.

Found and fixed by GPT 5.3 Codex.
2026-02-28 07:39:16 +01:00
ringabout
a3157537e1 allows implicitRangeConvs for literals (#25542)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-25 19:10:00 +01:00
ringabout
74499e4561 fixes #21281; proc f(x: static[auto]) doesn't treat x as static (#25543)
fixes #21281
2026-02-25 19:09:24 +01:00
ringabout
b51be75613 fixes #25509; removes void fields from a named tuple type (#25515)
fixes #25509

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-24 10:47:14 +01:00
ringabout
1451651fd9 enable --warning:ImplicitRangeConversion (#25477)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-24 09:40:21 +01:00
Tomohiro
fb80f7707d fixes #16754 (#25519)
This PR allows passing the defining type to generic types in the right
side in a type definition like this:
```nim
type
  Foo = object
    x: Option[Foo]
```
I think generic types should be instanciated after all given arguments
are semchecked,
because generic types can access information about them.
(for example, `Option[T]` in std/option checks if `T` is a pointer like
type)
But in this case, need to instanciate `Option[Foo]` before type of
`Foo.x` is determined.
2026-02-24 09:39:06 +01:00
ringabout
e58acc2e1e fixes #25005; new doesn't work with ref object (#25532)
fixes #25005

In `semTypeIdent`, when resolving a typedesc parameter inside a generic
instantiation, the code took a shortcut: it returned the symbol of the
element type (`bound = result.typ.elementType.sym`). However, for
generic types like `RpcResponse[T] = ref object`, the instantiated
object type (e.g., `RpcResponse:ObjectType[string]`) is a copy with a
new type ID but still points to the same symbol as the uninstantiated
generic body type. That symbol's .typ refers to the original
uninstantiated type, which still contains unresolved generic params `T`
2026-02-23 13:40:31 +01:00
Andreas Rumpf
6badeb1b4d yrc progress (#25534) 2026-02-23 13:39:55 +01:00
Zoom
7c873ca615 Feat: std: parseopt parser modes (#25506)
Adds configurable parser modes to std/parseopt module. **Take two.**

Initially solved the issue of not being able to pass arguments to short
options as you do with most everyday CLI programs, but reading the tests
made me add more features so that some of the behaviour could be changed
and here we are.

**`std/parseopt` now supports three parser modes** via an optional
`mode` parameter in `initOptParser` and `getopt`.

Three modes are provided:
- `NimMode` (default, fully backward compatible),
- `LaxMode` (POSIX-inspired with relaxed short option handling),
- `GnuMode` (stricter GNU-style conventions).

The new modes are marked as experimental in the documentation.

The parser behaviour is controlled by a new `ParserRules` enum, which
provides granular feature flags that modes are built from. This makes it
possible for users with specific requirements to define custom rule sets
by importing private symbols, this is mentioned but clearly marked as
unsupported.

**Backward compatibility:**

The default mode preserves existing behaviour completely, with a single
exception: `allowWhitespaceAfterColon` is deprecated.

Now, `allowWhitespaceAfterColon` doesn't make much sense as a single
tuning knob. The `ParserRule.prSepAllowDelimAfter` controls this now.
As `allowWhitespaceAfterColon` had a default, most calls never mention
it so they will silently migrate to the new `initOptParser` overload. To
cover cases when the proc param was used at call-site, I added an
overload, which modifies the default parser mode to reflect the required
`allowWhitespaceAfterColon` value. Should be all smooth for most users,
except the deprecation warning.

The only thing I think can be classified as the breaking change is a
surprising **bug** of the old parser:

```nim
let p = initOptParser("-n 10 -m20 -k= 30 -40",  shortNoVal =  {'v'})
#                                     ^-disappears
```

This is with the aforementioned `allowWhitespaceAfterColon` being true
by default, of course. In this case the `30` token is skipped
completely. I don't think that's right, so it's fixed.


Things I still don't like about how the old parser and the new default
mode behave:

1. **Parser behaviour is controlled by an emptiness of two containers**.
This is an interesting approach. It's also made more interesting because
the `shortNoVal`/`longNoVal` control both the namesakes, but *and also
how their opposites (value-taking opts) work*.
---

**Edit:**

2. `shortNoVal` is not mandatory:
    ```nim
	let p = initOptParser(@["-a=foo"], shortNoVal = {'a'})
	# Nim, Lax parses as: (cmdShortOption, "a", "foo") 
	# GnuMode  parses as: (cmdShortOption, "a", "=foo")
	```
In this case, even though the user specified `a` as no no-val, parser
ignores it, relying only on the syntax to decide the kind of the
argument. This is especially problematic with the modes that don't use
the rule `prShortAllowSep` (GnuMode), in this case the provided input is
twice invalid, regardless of the `shortNoVal`.

With the current parser architecture, parsing it this way **is
inevitable**, though. We don't have any way to signal the error state
detected with the input, so the user is expected to validate the input
for mistakes.
Bundling positional arguments is nonsensical and short option can't use
the separator character, so `[cmd "a", arg "=foo"]` and `[cmd "a", cmd
"=", cmd "f"...]` are both out of the question **and** would complicate
validating, requiring keeping track of a previous argument. Hope I'm
clear enough on the issue.
	
**Future work:**

1. Looks like the new modes are already usable, but from the discussions
elsewhere it looks like we might want to support special-casing
multi-digit short options (`-XX..`) to allow numerical options greater
than 9. This complicates bundling, though, so requires a bit of thinking
through.

2. Signaling error state?

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
2026-02-16 16:06:18 +01:00
ringabout
97fed258ed fixes #25475; incompatible types errors for array types with different index types (#25505)
fixes #25475

```nim
var x: array[0..1, int] = [0, 1]
var y: array[4'u..5'u, int] = [0, 3]

echo x == y
```

sigmatch treats array compatibility by element type + length, not by the
index (range) type. Perhaps backend should do the same check
2026-02-13 22:59:21 +01:00
Yuriy Glukhov
937e647f4f Importc codegen fix (#25511)
This fixes two issues with impotc'ed types.
1. Passing an importc'ed inherited object to where superclass is
expected emitted `v.Sup` previously. Now it emits `v`, similar to cpp
codegen.
2. Casting between different nim types that resolve to the same C type
previously was done like `*(T*)&v`, now it is just `v`.
2026-02-13 13:29:01 +01:00
Andreas Rumpf
b41049988f attempt to fix final issue with Nim's multi-threaded allocator (#25513) 2026-02-13 11:53:17 +01:00
ringabout
94008531c1 fixes #25457; make rawAlloc support alignment (#25476)
fixes https://github.com/nim-lang/Nim/issues/25457

Small chunks allocate memory in fixed-size cells. Each cell is
positioned at exact multiples of the cell size from the chunk's data
start, which makes it much harder to support alignment

```nim
sysAssert c.size == size, "rawAlloc 6"
if c.freeList == nil:
  sysAssert(c.acc.int + smallChunkOverhead() + size <= SmallChunkSize,
            "rawAlloc 7")
  result = cast[pointer](cast[int](addr(c.data)) +% c.acc.int)
  inc(c.acc, size)
```

See also https://github.com/nim-lang/Nim/pull/12926 

While using big trunk, each allocation gets its own chunk
2026-02-11 11:33:31 +01:00
ringabout
c346a2b228 fixes #25464; infer =dup for distinct types (#25501)
fixes #25464

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-11 10:46:34 +01:00
Andreas Rumpf
f62669a5d5 Yrc typos and omissions (#25500) 2026-02-10 13:21:35 +01:00
Andreas Rumpf
a690a9ac90 YRC: threadsafe cycle collection for Nim (#25495)
First performance numbers:

time tests/arc/torcbench   -- YRC
true peak memory: true

real    0m0,163s
user    0m0,161s
sys     0m0,002s


time tests/arc/torcbench   -- ORC
true peak memory: true

real    0m0,107s
user    0m0,104s
sys     0m0,003s


So it's 1.6x slower. But it's threadsafe and provably correct. (Lean and
model checking via TLA+ used.)

Of course there is always the chance that the implementation is wrong
and doesn't match the model.
2026-02-10 00:04:11 +01:00
ringabout
ae5f864bff fixes #25494; [regression] Crash on enum ranges as default parameters in generic procs (#25496)
fixes #25494;
2026-02-09 11:50:45 +01:00
ringabout
12a2333817 fixes #25464; gives a deprecated warning when =dup is not provided while there being a custom =copy (#25485)
Gives a deprecated warning to keep backwards compatibility

fixes #25464
2026-02-06 02:19:46 +01:00
Yuriy Glukhov
296b2789b5 Fixes #25340 (#25389) 2026-02-06 00:54:04 +01:00
ringabout
a04f720217 fixes #25482; ICE leaking temporary 3 slotTempInt (#25483)
fixes #25482
2026-02-05 05:41:54 +01:00
ringabout
bfc2786718 fixes #24706; Warn on implicit range downsizing (#25451)
fixes #24706
2026-02-01 17:06:33 +01:00
Tomohiro
88e7adfcb7 fixes #25459; hashType returns different hash from instantiated generics with distinct types (#25471)
`hashType` proc returned the same hash value from different instanced
generics types like `D[int64]` and `D[F]`.
That caused the struct type with wrong field types.

object/tuple type size check code is generated when it is compiled with
`-d:checkAbi` option.
2026-02-01 07:01:55 +01:00
Gianmarco
e7809364b3 Make it so that every feature can be used in panicoverride files (#25300)
Refer to #25298
2026-01-24 16:01:21 +01:00
ringabout
81610095e6 fixes #25441; fixes #7355; deletes void args from the argument list (#25455)
fixes #25441; fixes #7355

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2026-01-24 06:08:38 +01:00
Andreas Rumpf
469e1377cd IC: progress (#25453) 2026-01-24 06:07:41 +01:00
ringabout
f44700e638 fixes #19831; add --styleCheck:warning (#25456)
fixes #19831
2026-01-23 22:50:00 +01:00
ringabout
ace09b3cab fixes #25074; Long integer literal truncated without warning (#25449)
fixes #25074

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-01-23 14:52:37 +01:00
ringabout
39864980d1 fixes #25446; [FieldDefect] with static: discard cast[pointer](default(pointer)) (#25448)
fixes #25446

supports this since `static: discard cast[pointer](nil)` works
2026-01-22 09:50:25 +01:00
Andreas Rumpf
86a4ddc847 IC: remember which modules are from the NIF cache (#25443) 2026-01-22 04:26:20 +01:00
ringabout
9a23ff36bd fixes #25400; Naked raised causes wrong exception effect (#25422)
fixes #25400

infers `Exception` for Naked raised
2026-01-16 15:25:14 +01:00
ringabout
40480fe348 fixes #25419; lift magic types to typeclasses (#25421)
fixes #25419
2026-01-14 16:25:52 +01:00
Jake Leahy
c1e381ae8d Raw switch for jsondoc (#24568)
Implements #21928

Adds a `--raw` (since thats what the original issue used, suggestions
welcome) switch which stops the jsondoc gen from rendering rst/markdown.

Implemented by making `genComment` check if it needs to return the raw
string or not. This required switching the related procs to using
`Option` to handle how `nil` values were returned before. The `nil`
returns were eventually ignored so just ignoring `none(T)` has the same
effect.

Doesn't support `runnableExamples` since jsondocs doesn't support them
either
2026-01-11 18:39:01 +08:00
Copilot
83d7d8c634 Add test case for jsffi type mismatch error (#16726) (#25429)
Issue #16726 reported an internal compiler error (`semcall.nim(229, 18)
nArg != nil`) when calling `toJs` with invalid arguments. The bug has
been fixed in the current codebase but lacked a regression test.

```nim
import std/jsffi
let a = toJs(3)
let b = a.toJs(int)  # Now produces: Error: type mismatch
                      # Previously: internal error
```

**Changes:**
- Added `tests/js/t16726.nim` to verify proper type mismatch error is
reported instead of internal compiler error

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>internal error: semcall.nim(229, 18) nArg !=
nil</issue_title>
> <issue_description>### Example
> the code below should give a clean CT error, not an internal error
> ```nim
> import std/jsffi
> let a = toJs(3)
> let b = a.toJs(int)
> ```
> 
> ### Current Output
> nim r -b:js main
> compiler/semcall.nim(229, 18) `nArg != nil` 
> 
> ### Expected Output
> proper CT error
> 
> ### Additional Information
> 1.5.1 41965880ce
> </issue_description>
> 
> <agent_instructions>adds a test case for it and verify it by `./koch
temp js -r test.nim` before committing</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@ringabout</author><body>
> related:
https://github.com/nim-lang/Nim/issues/15607</body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes nim-lang/Nim#16726

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2026-01-10 21:18:39 +08:00
Andreas Rumpf
01eedd916c IC: progress (#25420) 2026-01-09 13:10:04 +01:00
ringabout
89c8f0aa49 closes #23394; adds a test case (#25416)
closes #23394
2026-01-07 09:32:25 +01:00
Andreas Rumpf
d3be5e5e13 IC: need a more recent Nimony for its improved Nifler tool (#25412) 2026-01-06 00:16:19 +01:00