Commit Graph

22595 Commits

Author SHA1 Message Date
Zoom
ecdcffed4b Mark system.newStringUninit sideeffect-free (#24813)
- Allows using with `--experimental:strictFuncs`
- `{.cast(noSideEffect).}:` inside the proc was required to mutate
`s.len`, same as used in `newSeqImpl`.
- Removed now unnecessary `noSideEffect` casts in `system.nim`
- 
Closes #24811

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2025-03-28 22:06:22 +08:00
ringabout
58b1f28177 fixes implicitConv discarding flags (#24817)
follow up https://github.com/nim-lang/Nim/pull/24809
ref https://github.com/nim-lang/Nim/pull/24815
2025-03-28 12:52:45 +01:00
ringabout
73112d64a3 fixes #24793; Revert "remove special treatments of sinking const sequences (#24812)
fixes #24793

There doesn't seem to have a better solution
2025-03-26 23:49:00 +08:00
Zoom
b82d7e8ba1 stdlib: substr uses copymem if available, improve docs (#24792)
- `system.substr` now uses `copymem` when available, introducing a small
template for nimvm detection (#12517 #12518)
- Docs are updated to clarify behaviour on out-of-bounds input
- Runnable examples cover more edge cases and do not repeat between
overloads
- Docs now explain the difference between overloads

What bothers me is that the `substr*(a: openArray[char]): string =`
which was added by @beef331 is practically an implementation of #14810,
which is just a conversion from `openArray` to `string` but somehow it
ended up being a `substr` overload, even though its behaviour is totally
different, _the "substringing" is performed by a previous step_
(conversion to openArray) and the bounds are not checked. I'm not sure
it's that great for overloads to differ in subtle ways so much.

What are the cases that `substr` covers now, that prohibit renaming it
to `toString` (or something like that)?
2025-03-25 21:06:40 +01:00
ringabout
ddd83f8d8a fixes #24800; Invalid C code generation with a method, case object in refc (#24809)
fixes #24800

This PR avoids a conversion from `sink T` to `T`

I will add a test case
2025-03-25 20:42:40 +01:00
握猫猫
8e36fb0fec Update nativesockets.nim, namelen should be the len of name (#24810)
In other places where `getsockname` is called, the size of the 'name' is
used.


d573578b28/lib/pure/nativesockets.nim (L347-L351)

d573578b28/lib/pure/nativesockets.nim (L585-L595)

d573578b28/lib/pure/nativesockets.nim (L622-L624)

d573578b28/lib/pure/nativesockets.nim (L347-L350)

I have checked the [Windows
documentation](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname#remarks),
and it describes it like this: "On call, the namelen parameter contains
the size of the name buffer, in bytes. On return, the namelen parameter
contains the actual size in bytes of the name parameter."


[https://www.man7.org/linux/man-pages/man2/getsockname.2.html](https://www.man7.org/linux/man-pages/man2/getsockname.2.html)
say:
The addrlen argument should be initialized to indicate the amount of
space (in bytes) pointed to by addr.
2025-03-25 20:32:12 +01:00
lit
d573578b28 repl: support eof, define object with fields (#24784)
For `nim secret`:

- **fix(repl): eof(ctrl-D/Z) and ctrl-C were ignored**
- **feat(repl): continueLine  figures section, constr, bool ops**

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2025-03-25 07:41:17 +01:00
Zoom
909f3b8b79 [feature] stdlib: strutils.multiReplace for character sets (#24805)
Multiple replacements based on character sets in a single pass. Useful
for string sanitation. Follows existing `multiReplace` semantics.

Note: initially copied the substring version logic with a `while` and a
named block break, but Godbolt showed it had produced slightly larger
assembly using higher registers than the final version.

- [x] Tests
- [x] changelog.md
2025-03-25 07:40:01 +01:00
ringabout
d15705e05b fixes usenimrtl with useMalloc (#24804)
Follow up https://github.com/nim-lang/Nim/pull/19512

ref https://github.com/nim-lang/Nim/issues/24794

Otherwise, `/Users/blue/Desktop/Nim/lib/system/mm/malloc.nim(4, 1)
Error: redefinition of 'allocImpl'; previous declaration here:
/Users/blue/Desktop/Nim/lib/system/memalloc.nim(51, 8)`


In `proc allocImpl*(size: Natural): pointer {.noconv, rtl, tags: [],
benign, raises: [].}`, `rtl` means it is an `importc` function instead
of a proc forward decl.
2025-03-24 22:52:43 +01:00
ringabout
0b9ed84d32 disable implicit sinkinference for stdlibs (#24803)
ref https://github.com/nim-lang/Nim/issues/24794
2025-03-24 14:07:45 +01:00
metagn
fcba14707a disable "dest register is set" for vm statements (#24797)
closes #24780

This proc `genStmt` is only called to run the VM in `vm.evalStmt`,
otherwise it's not used in vmgen. Now it acts the same as `proc
gen(PCtx, PNode)`, used by `discard` statements, which just calls
`freeTemp` on the dest if it was set rather than erroring.
2025-03-23 06:59:06 +03:00
ringabout
482662d198 fixes #24721; Table add missing sink (#24724)
fixes #24721
2025-03-22 22:48:21 +01:00
Esteban C Borsani
9ace1f97ac Fix SIGSEGV when closing SSL async socket while sending/receiving (#24795)
Async SSL socket SIGSEGV's sometimes when calling socket.close() while
send/recv. The issue was found here
https://github.com/nitely/nim-hyperx/pull/59.

Possibly related: #24024

This can occur when closing the socket while sending or receiving,
because `socket.sslHandle` is freed. The sigsegv can also occur on calls
that require `socket.bioIn` or `socket.bioOut` because those use
`socket.sslHandle` internally. This PR checks sslHandle is set before
doing any operation that requires it.
2025-03-22 16:38:38 +01:00
Angus Gibson
1d32607575 Allow parsing year "00" with "yy" pattern (#24785)
The "yy" pattern is relative to the current century, so year "00" should
be valid.
2025-03-19 08:15:54 +01:00
ringabout
7c5d005510 fixes #10625; setjmp on linux mangles ebp leading to early collection (#24787)
fixes #10625
2025-03-18 18:51:34 +08:00
Ryan McConnell
2b699bca53 new-style concepts - small bugfix (#24778) 2025-03-15 15:05:14 +01:00
metagn
fb93295344 fix compound inheritance penalty (#24775)
fixes #24773

`c.inheritancePenalty` is supposed to be used for the entire match, but
in these places the inheritance penalty of a single argument overrides
the entire match penalty. The `+ ord(c.inheritancePenalty < 0)` is
copied from other places that use the same idiom, the intent is that the
existing penalty changes from -1 to 0 first to mark that it participates
in inheritance before adding the inheritance depth.

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
2025-03-12 17:31:33 +01:00
ringabout
9ebfa7973a fixes generic types sink T cannot be inferred for passed arguments (#24761)
Otherwise, `sink T` is kept as it is. This PR treats sink types as its
base types for the arguments. So the concept would match both cases

Required by https://github.com/nim-lang/Nim/pull/24724
2025-03-12 17:31:19 +01:00
lit
4f32624641 fixes #24772: system.NaN was negative when C (#24774)
fixes #24772

The old implementation was said to copied  from Windows SDK,

but you can find the newer SDK's definition is updated and the sign is
reversed compared to the old.


Also, `__builtin_nanf("")` is used if available,
which is more efficient than previous (In x86_64 gcc, latter produces
32B code but former just 8B).
2025-03-12 17:30:08 +01:00
ringabout
dfa482e292 fixes #24770; Thread local not registed as GC root when =destroy exists (#24776)
fixes #24770

e.g. `seq[(ObjectWithDestructors, string)]`/ For refc, a seq with
elements that have destructors will have `hasAsgn` flags. The flag is
the criteria whether a seq is thought as `containsGarbageCollectedRef`.
i.e. whether to `registerTraverseProc` for the type.
The culprit seems to be that `searchTypeForAux` doesn't consider the
element type of sequence, even it contains a string that should belong
to `GarbageCollectedRef`.

With this PR:

It now generates

```
nimRegisterThreadLocalMarker(TM__mSF73dT1lSI7DG58StKHLQ_5);
```

in refc
2025-03-12 17:29:30 +01:00
metagn
82891e6850 give hint for forward declarations with unknown raises effects (#24767)
refs #24766

Detect when we track a call to a forward declaration without explicit
`raises` effects, then when the `raises` check fails for the proc, give
a hint that this forward declaration was tracked as potentially raising
any exception.
2025-03-11 14:24:45 +01:00
Ryan McConnell
850f327713 folding const expressions with branching logic (#24689)
motivating example:
```nim
iterator p(a: openArray[char]): int =
  if a.len != 0:
    if a[0] != '/':
      discard
for t in p(""): discard
```
The compiler wants to evaluate `a[0]` at compile time even though it is
protected by the if statement above it. Similarly expressions like
`a.len != 0 and a[0] == '/'` have problems. It seems like the logic in
semfold needs to be more aware of branches to positively identify when
it is okay to fail compilation in these scenarios. It's a bit tough
though because it may be the case that non-constant expressions in
branching logic can properly protect some constant expressions.
2025-03-11 10:01:32 +01:00
metagn
38ad336c69 fix tuple nodes from VM inserting hidden conv to keep old type (#24756)
fixes #24755, refs #24710

Instead of using the node from `indexTypesMatch` which inserts a hidden
conv node, just change the type of the node back to the old type
directly
2025-03-11 10:00:37 +01:00
ringabout
a7711d452d fixes #24754; {.gcsafe.} block breaks move analysis (#24757)
fixes #24754
2025-03-11 09:59:55 +01:00
metagn
e2e7790779 fix canRaise for non-proc calls (#24752)
fixes #24751

`typeof` leaves the object constructor as a call node for some reason,
in this case it tries to access the first child of the type node but the
object has no fields so the type field is empty. Alternatively the
optimizer can stop looking into `typeof`
2025-03-11 09:59:21 +01:00
Michael Lee
dfd2987118 Add linking options for tinycc backend (#24750)
### Issue

When using `tcc` as backend to compile a trivial program

```
nim c  --cc:tcc  --skipCfg a.nim
```

, errors reported:

```
tcc: error: undefined symbol 'fabs'
```

### Solution

`fabs` belongs to libm. With these two options added, one can compile
with an additional clib option:

```
nim c  --cc:tcc  --skipCfg --clib:m a.nim
```
2025-03-11 09:58:22 +01:00
ringabout
e2d4791229 fixes move for getPotentialWrites (#24753)
`move` would modify parameters as well
2025-03-11 09:57:48 +01:00
ringabout
ccb40024c6 remove special treatments of sinking const sequences (#24763) 2025-03-11 09:56:48 +01:00
Laylie
f8294ce06e Fix scanTuple undeclared identifier 'scanf' (#24759)
Without this fix, trying to use `scanTuple` in a generic proc imported
from a different module fails to compile (`undeclared identifier:
'scanf'`):

```nim
# module.nim
import std/strscans

proc scan*[T](s: string): (bool, string) =
  s.scanTuple("$+")
```

```nim
# main.nim
import ./module
 
echo scan[int]("foo")
```

Workaround is to `export scanf` in `module.nim` or `import std/strscans`
in `main.nim`.
2025-03-10 22:47:03 +08:00
ringabout
b8302cdd97 implements internal sink copy (#24747)
TODO:

- [x] other value types (arrays, strings, seqs, objects) 
- [x] replaces https://github.com/nim-lang/Nim/pull/24731
- [x] improve code shape
- [ ] revert https://github.com/nim-lang/Nim/issues/24175
- [x] if possible, revert https://github.com/nim-lang/Nim/pull/23685
- [ ] if possible, revert https://github.com/nim-lang/Nim/pull/22229 and
https://github.com/nim-lang/Nim/pull/23764
- [ ] if possible, remove `if n.containsConstSeq:`
- [ ] if possible, always pass value (arrays, strings, seqs, tuples, or
even objects without custom hooks (?)) sinks by ref because this PR
should ensure these value types are not modified without a copy
- [x] fixes `say a, (b = move a; a)` for potential writes
https://github.com/nim-lang/Nim/pull/24753
2025-03-10 11:20:44 +01:00
Ryan McConnell
dfab30734b new-style concepts adjusments (#24697)
Yet another one of these. Multiple changes piled up in this one. I've
only minimally cleaned it for now (debug code is still here etc). Just
want to start putting this up so I might get feedback. I know this is a
lot and you all are busy with bigger things. As per my last PR, this
might just contain changes that are not ready.

### concept instantiation uniqueness
It has already been said that concepts like `ArrayLike[int]` is not
unique for each matching type of that concept. Likewise the compiler
needs to instantiate a new proc for each unique *bound* type not each
unique invocation of `ArrayLike`

### generic parameter bindings
Couple of things here. The code in sigmatch has to give it's bindings to
the code in concepts, else the information is lost in that step. The
code that prepares the generic variables bound in concepts was also
changed slightly. Net effect is that it works better.
I did choose to use the `LayedIdTable` instead of the `seq`s in
`concepts.nim`. This was mostly to avoid confusing myself. It also
avoids some unnecessary movings around. I wouldn't doubt this is
slightly less performant, but not much in the grand scheme of things and
I would prefer to keep things as easy to understand as possible for as
long as possible because this stuff can get confusing.

### various fixes in the matching logic
Certain forms of modifiers like `var` and generic types like
`tyGenericInst` and `tyGenericInvocation` have logic adjustments based
on my testing and usage

### signature matching method adjustment
This is the weird one, like my last PR. I thought a lot about the
feedback from my last attempt and this is what I came up with. Perhaps
unfortunately I am preoccupied with a slight grey area. consider the
follwing:
```nim
type
  C1 = concept
    proc p[T](s: Self; x: T)
  C2[T] = concept
    proc p(s: Self; x: T)
```
It would be temping to say that these are the same, but I don't think
they are. `C2` makes each invocation distinct, and this has important
implications in the type system. eg `C2[int]` is not the same type as
`C2[string]` and this means that signatures are meant to accept a type
that only matches `p` for a single type per unique binding. For `C1` all
are the same and the binding `p` accepts multiple types. There are
multiple variations of this type classes, `tyAnything` and the like.

The make things more complicated, an implementation might match:
```nim
type
  A = object
  C3 = concept
    proc p(s: Self; x:  A)
```
if the implementation defines:
```nim
proc p(x: Impl; y: object)
```

while a concept that fits `C2` may be satisfied by something like:
```nim
proc p(x: Impl; y: int)
proc spring[T](x: C2[T])
```
it just depends. None of this is really a problem, it just seems to
provoke some more logic in `concepts.nim` that makes all of this (appear
to?) work. The logic checks for both kinds of matches with a couple of
caveats. The fist is that some unbind-able arrangements may be matched
during overload resolution. I don't think this is avoidable and I
actually think this is a good way to get a failed compilation. So, first
note imo is that failing during binding is preferred to forcing the
programming to write annoying stub procs and putting insane gymnastics
in the compiler. Second thing is: I think this logic is way to accepting
for some parts of overload resolutions. Particularly in `checkGeneric`
when disambiguation is happening. Things get hard to understand for me
here. ~~I made it so the implicit bindings to not count during
disambiguation~~. I still need to test this more, but the thought is
that it would help curb excessive ambiguity errors.

Again, I'm sorry for this being so many changes. It's probably
inconvenient.

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2025-03-07 18:14:00 +01:00
metagn
569d02e212 generate tyFromExpr for typeof static param with generic base type (#24745)
fixes #24743, refs #24718

We cannot do this in general for any expression with generic type
because the `typeof` logic is called for things like `type Foo` in:

```nim
type Foo[T] = object

proc init(_: type Foo) = discard
```

We also cannot use `containsUnresolvedType` to work around this specific
case because the base type of `static[auto]` is not unresolved, it is a
typeclass that isn't lifted to a parameter. The behavior of generating
`tyFromExpr` is also consistent with pre-2.0, so we do this in this
special case of `static`.
2025-03-05 13:47:56 +01:00
metagn
e39d152b89 handle ranges in annotateType for set constructors (#24737)
fixes #24736

The VM can produce integer nodes with no types as set elements, which
are later reannotated in `semmacrosanity.annotateType`. However the case
of ranges was not handled properly. Not sure why this is a regression,
probably unrelated but will have to see the bisect result to make sure.

Note. Originally tried to fix this in `opcInclRange`, generated for and
only for range expressions in set constructors, this seems to add the
range node directly to the set node without checking if it has overlap
with the existing elements by calling `nimsets` so an expression like
`{cctNone, cctNone..cctHeader}` can produce `{0, 0..5}`. Doesn't seem to
cause problems but `opcIncl` for single elements does check for overlap.

Something else to note is that integer nodes produced by `nimsets` have
proper types, so another option instead of relying on semmacrosanity to
fix this would be to make `opcIncl` and `opcInclRange` call `nimsets` to
add to the set node, but this might lose performance.
2025-02-28 17:23:19 +03:00
ringabout
7e8a650729 sink tuples by values (#24731)
A reduced case
```nim
type AnObject = tuple
  a: string
  b: int
  c: int

proc mutate(a: sink AnObject) =
  `=wasMoved`(a)
  echo 1

# echo "Value is: ", obj.value
proc bar =
  mutate(("1.2", 0, 0))

bar()
```
2025-02-27 18:33:35 +01:00
metagn
0cb4cd159e move nim version in issue template to the top (#24733)
The point is to move it out of the current place between "Description"
and "Current Output" as often these are related to each other and
including the nim version in the middle breaks the flow of reading. I
also thought of moving it below "Expected Output" but this felt too low
for a required field and also has the same problem of overshadowing the
remaining sections. Not sure if it being at the top is annoying in some
other way though.
2025-02-27 16:48:53 +01:00
ringabout
7ecb35115b fixes #24339; underscores used with fields and fieldPairs (#24341)
fixes #24339
2025-02-27 16:48:15 +01:00
ringabout
b421d0f8ee fixes #19728; setLen slow when shrinking seq due to zero-filling of released area (#24683)
fixes #19728

don't zero-filling memory for "trivial types" without destructor in
refc. I tested locally with internal apis.
2025-02-27 16:45:58 +01:00
ringabout
c452275e29 fixes #24705; encode static parameters into function names for debugging (#24707)
fixes #24705

```nim
proc xxx(v: static int) =
  echo v
xxx(10)
xxx(20)
```

They are mangled as `_ZN14titaniummangle7xxx_s10E` and
`_ZN14titaniummangle7xxx_s20E` with `--debugger:native`. Static
parameters are prefixed with `_s` to distinguish simple cases like
`xxx(10, 15)` and `xxx(101, 5)` if `xxx` supports two `static[int]`
parameters
2025-02-27 16:45:04 +01:00
metagn
a18dcca744 don't try to infer array range to unresolved range (#24709)
fixes #24708
2025-02-26 22:21:03 +01:00
metagn
49dfc3a0d4 convert tuple constructors from VM back to original types (#24710)
fixes #24698

The same aim as #24224 but for tuple constructors. The difference here
is that the type of a tuple constructor is always going to be valid
unlike array constructors which can have `seq` etc types, so we can just
generate a conversion again. If the conversion fails, it is ignored
similar to #24611, this is to protect against modified typed nodes in
macros.

Also #24611 was only adapted to `semTupleFieldsConstr` and not
`semTuplePositionsConstr`, this is now fixed.
2025-02-26 22:20:41 +01:00
Michael Lee
16280d4e49 Improve bash completion support (#24692)
Following https://github.com/nim-lang/nimble/pull/1347, this patch adds
bash completion support for `nim`, `nimgrep`, `nimpretty`, `nimsuggest`.
2025-02-26 22:19:46 +01:00
ringabout
a7a8e364ea fixes #12340; enable refc with move analyzer (#23782)
fixes https://github.com/nim-lang/Nim/issues/12340
2025-02-25 20:20:24 +01:00
Ryan McConnell
d94e535145 Make koch friendlier to offline environments (#24713) 2025-02-25 17:10:30 +01:00
metagn
514a25c9a2 always skip static types for result of typeof (#24718)
fixes #24715

In generic typechecking, unresolved static param symbols (i.e.
`skGenericParam`) have [the static type
itself](1f8da3835f/compiler/semexprs.nim (L1483-L1485))
as their type when used in an expression. This is not the case when the
static param is resolved (the type is wrapped in static when necessary),
but semchecking of types and generic typechecking expects the type of
the value to be wrapped in `static` (at least `array[N, int]` breaks).
So for now, to solve the issue, `typeof` just skips static types.
2025-02-25 17:09:04 +01:00
ringabout
e449813c61 fixes #24725; Invalid =sink generated for pure inheritable object (#24726)
fixes #24725

`lacksMTypeField` doesn't take the base types into consideration. And
for ` {.inheritable, pure.}`, it shouldn't generate a `m_type` field.
2025-02-25 17:08:22 +01:00
ringabout
93fb219f10 undeprecates var T destructors (#24716)
Both cases are now valid. Though, it could be problematic to mix two
cases together as built-in types have non var T destructors
2025-02-25 17:05:59 +01:00
metagn
1f8da3835f keep param pragmas in typed proc AST (#24711)
fixes #24702
2025-02-22 21:22:30 +01:00
ringabout
1af88a2d20 always mangle local variables (#24681)
ref #24677
2025-02-19 23:03:58 +01:00
lit
91e8e605d0 fix(dollar): $NaN -> "NaN", $Inf -> "Infinity" only when js (#24695)
ref nimpylib/pylib#44

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2025-02-19 23:03:28 +01:00
ringabout
f0b5bf359e fixes ORC memory leaks; marks hooks with optQuirky (#24701)
closes https://github.com/nim-lang/Nim/pull/24686
closes #24693

```nim
# v.nim
import std/[json]

var test: seq[string]
var testData: JsonNode
try:
  ## Fails
  testData = parseJson("""[{"id": 1"}, {"id": "2"}]""")

  ## Works
  # testdata = parseJson("""[{"id": "1"}, {"id": "2"}]""")
  
  ## Fails
  # let stream = newStringStream("""[{"id": 1"}, {"id": "2"}]""")
  # testData = parseJson(stream, "input", false, false)
  # stream.close()
  
except:
  testData = %* []
for t in testData:
  test.add(t["id"].getStr())
echo $test
```

With this PR:

```
==66425== LEAK SUMMARY:
==66425==    definitely lost: 0 bytes in 0 blocks
==66425==    indirectly lost: 0 bytes in 0 blocks
==66425==      possibly lost: 0 bytes in 0 blocks
==66425==    still reachable: 16,512 bytes in 2 blocks
==66425==         suppressed: 0 bytes in 0 blocks
==66425== Reachable blocks (those to which a pointer was found) are not shown.
==66425== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==66425== 
==66425== For lists of detected and suppressed errors, rerun with: -s
==66425== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```
2025-02-19 23:02:28 +01:00