Commit Graph

133 Commits

Author SHA1 Message Date
Yuriy Glukhov
97c41c0f15 Fixes #25330 (#25336)
Fixed state optimizer. It did not replace deleted states in
`excLandingState`.

(cherry picked from commit 8f8814b495)
2025-12-05 15:29:45 +01:00
Yuriy Glukhov
800384176e Fixes #25261 (#25310)
Returning or yielding from a closureiter must restore "external"
exception, but `popCurrentException` from `blockLeaveActions` was
getting in the way. So now `blockLeaveActions` doesn't emit
`popCurrentException` for returns in closureiters. I'm not a fan of this
"abstraction leakage", but don't see a better solution yet. Any input is
much appreciated.

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
(cherry picked from commit 6656084004)
2025-11-27 19:03:50 +01:00
ringabout
4efece995e fixes #25251; SIGBUS with iterator over const Table lookup - premature temporary destruction (#25255)
fixes #25251

enforce a copy if the arg is a deref of a lent pointer since the arg
could be a temporary that will go out of scope

(cherry picked from commit 6f73094263)
2025-11-07 12:33:53 +01:00
Yuriy Glukhov
365da2cb97 Fixes #25202 (#25244)
(cherry picked from commit 7af4e3eefd)
2025-10-28 13:50:59 +01:00
ringabout
8a5067912c fixes #21138; closure func used in the loop (#25196)
fixes #21138

(cherry picked from commit cc49bf07fe)
2025-09-29 08:45:49 +02:00
ringabout
a2e2da2ab2 fixes #25167; fixes deref type (#25195)
fixes #25167

(cherry picked from commit fed0053481)
2025-09-29 08:44:50 +02:00
ringabout
73d9194449 fixes #21476; internal error: proc has no result symbol (#25192)
fixes #21476

(cherry picked from commit 3e2852cb1b)
2025-09-26 08:56:09 +02:00
ringabout
4cbdebcd50 fixes #25121; [FieldDefect] with iterator-loop (#25130)
fixes #25121

(cherry picked from commit 0a8f618e2b)
2025-08-29 08:12:39 +02:00
Yuriy Glukhov
f783924fd8 Fixes #25038 (#25039)
(cherry picked from commit 6ab532fd0f)
2025-07-13 20:14:36 +02:00
Yuriy Glukhov
02f73120ae Fixes #21235, #23602, #24978, #25018 (#25030)
Reworked closureiter transformation.

- Convolutedly nested finallies should cause no problems now.
- CurrentException state now follows nim runtime rules (pushes and pops
appropriately), and mimics normal code, which is somewhat buggy, see
#25031
- Previously state optimization (removing empty states or extra jumps)
missed some opportunities, I've reimplemented it to do everything
possible to optimize the states. At this point any extra states or jumps
should be considered a bug.

The resulting codegen (compiled binaries) is also slightly smaller.

**BUT:**
- I had to change C++ reraising logic, see expt.nim. Because with
closure iters `currentException` is not always in sync with C++'s notion
of current exception. From my tests and understanding of C++ runtime
there should not be any problems, but I'm only 99% sure :)
- I've reused `nfNoRewrite` flag in one specific case during the
transformation. This flag is also used in term-rewriting logic. Again,
99% sure, these 2 scenarios will never intersect.

(cherry picked from commit 36f8cefa85)
2025-07-08 16:14:05 +02:00
metagn
a8d87c041c don't traverse inner procs to lift locals in closure iters (#24876)
fixes #24863, refs #23787 and #24316

Working off the minimized example, my understanding of the issue is: `n`
captures `r` as `:envP.r1` where `:envP` is the environment of `b`, then
`proc () = n()` does the lambda lifting of `n` again (which isn't done
if the `proc ()` is marked `{.closure.}`, hence the workaround) which
then captures the `:envP` as another field inside the `:envP`, so it
generates `:envP.:envP_2.r1` but the `.:envP_2` field is `nil`, so it
causes a segfault.

The problem is that the capture of `r` in `n` is done inside
`detectCapturedVars` for the surrounding closure iterator: inner procs
are not special cased and traversed as regular nodes, so it thinks it's
inside the iterator and generates a field access of `:envP` freely. The
lambda lifting version of `detectCapturedVars` ignores inner procs and
works off of symbol uses (anonymous iterator and lambda declarations
pretend their symbol is used).

As a naive solution, closure iterators now also ignore inner proc
declarations same as `lambdalifting.detectCapturedVars`, but unlike it
they also don't do anything for the inner proc symbols. Lambdalifting
seems to properly handle the lifted variables but in the worst case we
can also make sure `closureiters.detectCapturedVars` traverses inner
procs by marking every local of the closure iter used in them as needing
lifting (but not doing the lifting). This does not seem necessary for
now so it's not done (was done and reverted in [this
commit](9bb39a9259)),
but regressions are still possible

(cherry picked from commit c06bb6cc03)
2025-04-16 09:09:08 +02:00
metagn
380697d3ff ignore typeof in closure iterators (#24861)
fixes #24859

(cherry picked from commit f58cd51fc4)
2025-04-14 10:51:51 +02:00
ringabout
093f5a1de5 Makes except: panics on Defect (#24821)
implements https://github.com/nim-lang/RFCs/issues/557

It inserts defect handing into a bare except branch

```nim
try:
  raiseAssert "test"
except:
  echo "nope"
```

=>

```nim
try:
  raiseAssert "test"
except:
  # New behaviov, now well-defined: **never** catches the assert, regardless of panic mode
  raiseDefect()
  echo "nope"
```

In this way, `except` still catches foreign exceptions, but panics on
`Defect`. Probably when Nim has `except {.foreign.}`, we can extend
`raiseDefect` to foreign exceptions as well. That's supposed to be a
small use case anyway.

 `--legacy:noPanicOnExcept` is provided for a transition period.

(cherry picked from commit 26b86c8f4d)
2025-04-04 10:08:49 +02:00
metagn
316141162b test case haul to prevent pileup (#24525)
closes #6013, closes #7009, closes #9190, closes #12487, closes #12831,
closes #13184, closes #13252, closes #14860, closes #14877, closes
#14894, closes #14917, closes #16153, closes #16439, closes #17779,
closes #18074, closes #18202, closes #18314, closes #18648, closes
#19063, closes #19446, closes #20065, closes #20367, closes #22126,
closes #22820, closes #22888, closes #23020, closes #23287, closes
#23510

(cherry picked from commit aeb3fe9505)
2025-01-14 13:17:11 +01:00
metagn
9be3559ed2 consider calls as complex openarray assignment to iterator params (#24333)
fixes #13417, fixes #19703

When passing an expression to an `openarray` iterator parameter: If the
expression is a statement list (considered "complex"), it's assigned in
a non-deep-copying way to a temporary variable first, then this variable
is used as a parameter. If it's not a statement list, i.e. a call or a
symbol, the parameter is substituted directly with the given expression.
In the case of calls, this results in the call potentially being
executed more than once, or can cause redefined variables in the
codegen.

To fix this, calls are also considered as "complex" assignments to
openarrays, as long as the return type of the call is not `openarray` as
the generated assignment in that case has issues/is unimplemented
(caused a segfault [here in
datamancer](47ba4d81bf/src/datamancer/dataframe.nim (L1580))).

As for why creating a temporary isn't the default only with exceptions
for things like `nkSym`, the "non-deep-copying" way of assignment
apparently still causes arrays to be copied according to a comment in
the code. I'm not sure to what extent this is true: if it still happens
on ARC/ORC, if it happens for every array length, or if we can fix it by
passing arrays by reference. Otherwise, a more general way to assign to
openarrays might be needed, but I'm not sure if the compiler can easily
do this.

(cherry picked from commit d303c289fa)
2025-01-14 07:50:24 +01:00
Yuriy Glukhov
893c638485 Fixes #3824, fixes #19154, and hopefully #24094. Re-applies #23787. (#24316)
The first commit reverts the revert of #23787.
The second fixes lambdalifting in convolutedly nested
closures/closureiters. This is considered to be the reason of #24094,
though I can't tell for sure, as I was not able to reproduce #24094 for
complicated but irrelevant reasons. Therefore I ask @jmgomez, @metagn or
anyone who could reproduce it to try it again with this PR.

I would suggest this PR to not be squashed if possible, as the history
is already messy enough.

Some theory behind the lambdalifting fix:
- A closureiter that captures anything outside its body will always have
`:up` in its env. This property is now used as a trigger to lift any
proc that captures such a closureiter.
- Instantiating a closureiter involves filling out its `:up`, which was
previously done incorrectly. The fixed algorithm is to use "current" env
if it is the owner of the iter declaration, or traverse through `:up`s
of env param until the common ancestor is found.

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit 5fa96ef270)
2025-01-14 07:46:30 +01:00
metagn
bcfb30a8be shallow fold prevention for addr, nkHiddenAddr (#24322)
fixes #24305, refs #23807

Since #23014 `nkHiddenAddr` is produced to fast assign array elements in
iterators. However the array access inside this `nkHiddenAddr` can get
folded at compile time, generating invalid code. In #23807, compile time
folding of regular `addr` expressions was changed to be prevented in
`transf` but `nkHiddenAddr` was not updated alongside it.

The method for preventing folding in `addr` in #23807 was also faulty,
it should only trigger on the immediate child node of the address rather
than all nodes nested inside it. This caused a regression as outlined in
[this
comment](https://github.com/nim-lang/Nim/pull/24322#issuecomment-2419560182).

To fix both issues, `addr` and `nkHiddenAddr` now both shallowly prevent
constant folding for their immediate children.

(cherry picked from commit 52cf7dfde0)
2025-01-14 07:46:13 +01:00
metagn
22d2cf2175 disable closure iterator changes in #23787 unless -d:nimOptIters is enabled (#24108)
refs #24094, soft reverts #23787

#23787 turned out to cause issues as described in #24094, but the
changes are still positive, so it is now only enabled if compiling with
`-d:nimOptIters`. Unfortunately the changes are really interwoven with
each other so the checks for this switch in the code are a bit messy,
but searching for `nimOptIters` should give the necessary clues to
remove the switch properly later on.

Locally tested that nimlangserver works but others can also check.
2024-09-16 07:16:21 +02:00
ringabout
3a55bae53f enable closures tests for JS & implement finished for JS (#23521) 2024-09-09 14:20:40 +02:00
ringabout
c8af0996fd fixes #24033; Yielding from var fails with pairs and destructuring (#24046)
fixes #24033
2024-09-02 18:12:48 +02:00
Yuriy Glukhov
05df263b84 Optimize closure iterator locals (#23787)
This pr redefines the relation between lambda lifting and closureiter
transformation.

Key takeaways:
- Lambdalifting now has less distinction between closureiters and
regular closures. Namely instead of lifting _all_ closureiter variables,
it lifts only those variables it would also lift for simple closure,
i.e. those not owned by the closure.
- It is now closureiter transformation's responsibility to lift all the
locals that need lifting and are not lifted by lambdalifting. So now we
lift only those locals that appear in more than one state. The rest
remains on stack, yay!
- Closureiter transformation always relies on the closure env param
created by lambdalifting. Special care taken to make lambdalifting
create it even in cases when it's "too early" to lift.
- Environments created by lambdalifting will contain `:state` only for
closureiters, whereas previously any closure env contained it.

IMO this is a more reasonable approach as it simplifies not only
lambdalifting, but transf too (e.g. freshVarsForClosureIters is now gone
for good).

I tried to organize the changes logically by commits, so it might be
easier to review this on per commit basis.

Some ugliness:
- Adding lifting to closureiters transformation I had to repeat this
matching of `return result = value` node. I tried to understand why it
is needed, but that was just another rabbit hole, so I left it for
another time. @Araq your input is welcome.
- In the last commit I've reused currently undocumented `liftLocals`
pragma for symbols so that closureiter transformation will forcefully
lift those even if they don't require lifting otherwise. This is needed
for [yasync](https://github.com/yglukhov/yasync) or else it will be very
sad.

Overall I'm quite happy with the results, I'm seeing some noticeable
code size reductions in my projects. Heavy closureiter/async users,
please give it a go.
2024-07-03 22:49:30 +02:00
ringabout
35ec9c31bd fixes refc with non-var destructor; cancel warnings (#23156)
fixes https://forum.nim-lang.org/t/10807
2024-02-13 08:11:49 +01:00
ringabout
f7c6e04cfb fixes #19977; rework inlining of 'var openarray' iterators for C++ (#23258)
fixes #19977
2024-01-26 12:46:39 +01:00
ringabout
8484abc2e4 fixes #15924; Tuple destructuring is broken with closure iterators (#23205)
fixes #15924
2024-01-13 12:00:55 +01:00
ringabout
eb91cf991a fixes #22619; don't lift cursor fields in the hook calls (#22638)
fixes https://github.com/nim-lang/Nim/issues/22619

It causes double free for closure iterators because cursor fields are
destroyed in the lifted destructors of `Env`.

Besides, according to the Nim manual

> In fact, cursor more generally prevents object
construction/destruction pairs and so can also be useful in other
contexts.

At least, destruction of cursor fields might cause troubles.


todo
- [x] tests
- [x] revert a certain old PR

---------

Co-authored-by: zerbina <100542850+zerbina@users.noreply.github.com>
2023-09-05 10:31:28 +02:00
Bung
0b78b7f595 fix #22548;environment misses for type reference in iterator access n… (#22559)
* fix #22548;environment misses for type reference in iterator access nested in closure

* fix #21737

* Update lambdalifting.nim

* remove containsCallKinds

* simplify
2023-08-27 14:29:24 +02:00
Bung
989da75b84 fix #20891 Illegal capture error of env its self (#22414)
* fix #20891 Illegal capture error of env its self

* fix innerClosure too earlier, make condition shorter
2023-08-09 09:43:39 +02:00
ringabout
942c378659 fixes #22148; std/memfiles.memSlices nesting now fails with memory sa… (#22154)
* fixes #22148; std/memfiles.memSlices nesting now fails with memory safety capture violation

* adds a test case
2023-06-25 17:15:47 +02:00
ringabout
88114948c4 fixes #21110; duplicate proc definitions for inline iters (#21136)
fixes #21110; duplicate proc definitions for iters
2023-06-22 22:17:23 +02:00
Jason Beetham
686c75cef0 for loop expression can now have generated iterator's called (#21627)
A for expression now can have a generated iterator, allowing for more composable iterables
2023-04-08 11:40:43 +02:00
ringabout
f2dad94902 fixes #21306; fixes #20485; don't transform yields in the var section when introducing new local vars [backport: 1.6] (#21489)
* fixes #21306;  don't transform yields in the var section when introducing new local vars

* adds `inVarSection` so the var section in the var section is freshed

* use `isIntroducingNewLocalVars` to avoid yield transformations in var sections

* fixes comments
2023-03-10 14:19:31 +01:00
ringabout
4388636010 fixes #21043; fixes a named exception in the infixAs expression which generate an implicit uninitialized let statement (#21081)
* fixes #21043; fixes a named exception in the infixAs expression which generate an implicit uninitialized let statement

* Update compiler/sempass2.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2022-12-12 23:14:44 +08:00
ringabout
ef29987781 An unnamed break in a block now gives an UnnamedBreak warning (#20901)
* unnamed break in the block now gives an error

* bootstrap

* fixes

* more fixes

* break with label

* label again

* one moee

* Delete test5.txt

* it now gives a UnnamedBreak warning

* change the URL of bump back to the original one
2022-11-24 07:31:47 +01:00
Tanguy
008c3ec76a Fix double defer with break in closureiterators [backport] (#20630)
Fix double defer with break in closureiterators

Signed-off-by: Tanguy <tanguy@status.im>

Signed-off-by: Tanguy <tanguy@status.im>
2022-10-24 08:50:48 +02:00
ringabout
7739e23420 defaults to ORC (#19972)
* defaults to Orc

* bootstrap using refc

* use gc

* init orc defines

* unregister orc

* fix gc

* fix commands

* add prepareMutation for orc

* enable deepcopy for orc

* prepareMutation

* more fixes

* some cases

* bug #20081

* partial fixes

* partial fixes

* fixes command line

* more fixes

* build Nim with refc

* use gc

* more fixes

* rstore

* orc doesn't support threadpool

* more shallowCopy

* more fixes

* fixes unsafeNew

* workarounds

* small

* more fixes

* fixes some megatest

* tcodegenbugs1 refc

* fxies megatest

* build nimble with refc

* workaround tensordsl tests

* replace shallowCopy with move

* fixes action

* workaround

* add todo

* fixes important packages

* unpublic unregisterArcOrc

* fixes cpp

* enable windows

Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
2022-09-23 13:05:05 +02:00
metagn
86f7f4ffa5 remove deprecated type pragma syntax, fix bugs that required it (#20199)
* remove deprecated pragma syntax from 0.20.0

closes #4651, closes #16653 with a cheap fix for now due to
how early `tfFinal` is set

* remove type pragma between name and generics

* undo removal, try removing bind expression (0.8.14)

* fix test, unremove bind expr

* remove again

* Update changelog.md

Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>

* dependencies @ HEAD & weave test dependencies

* try fix package ci

Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
2022-09-03 09:52:13 +02:00
Yuriy Glukhov
0d734d7966 Fixed compilation of void closureiters with try stmt (#20138) [backport] 2022-08-03 08:46:36 +02:00
Tanguy
fb5fbf1e08 Fix nested finally handling in closureiters [backport] (#19933)
* Fix nested finally handling in closureiters

* Fix CI

* review comment

* third time the charm

* Update compiler/closureiters.nim

Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>

Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
2022-07-11 11:28:52 +02:00
Tanguy
ce4078acd4 Allow recursive closure iterators (#19939) 2022-06-30 23:19:04 +02:00
flywind
83dabb69ae Fix bug in freshVarForClosureIter. Fixes #18474 (#19675) [backport]
* Fix bug in freshVarForClosureIter. Fixes #18474.

freshVarForClosureIter was returning non-fresh symbols sometimes.
Fixed by making addField return the generated PSym.

* remove discardable

Co-authored-by: Nick Smallbone <nick@smallbone.se>
2022-04-04 12:05:23 +02:00
Andreas Rumpf
2beefb9aa0 fixes #19575 (#19596) [backport]
* fixes #19575

* better bugfix
2022-03-09 11:42:09 +01:00
flywind
9df195ef58 style usages part one (openarray => openArray) (#19321)
* style usages (openArray)

* revert doc changes
2022-01-04 13:29:50 +01:00
Jason Beetham
90bfd34250 '[]' can now be used for iterators (#18814) 2021-09-06 15:30:49 +02:00
Andreas Rumpf
73841ae194 fixes #14165, fixes #18739, fix the second example of #6269 (#18812) 2021-09-06 13:12:14 +02:00
flywind
061a9183f7 replace wrt with proper word (#18724)
* what does wrt mean?

* clarify
2021-08-22 06:21:53 +02:00
Timothee Cour
24445d31b3 improve several tests in testament (#18635)
* silence error output from template_various.nim

* any => auto in tests

* avoid showing failed for parseSpec since this is expected behavior in 2 cases: tincludefile.nim, tnav1.nim

* enforce InheritFromException

* fixup
2021-08-08 19:28:49 +02:00
Yuriy Glukhov
a6bd6c7ed8 Fixes #17849 (#18055) [backport:1.2]
* Fixes #17849
* Update compiler/closureiters.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2021-05-30 22:38:33 +02:00
flywind
13a2030014 follow up #17486 (#17492)
* fix nim js cmp fails at CT

* follow up #17486

* test more branches

* better
2021-03-24 08:49:05 +01:00
Juan Carlos
78a99587a4 Deprecate TaintedString (#15423)
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
2021-01-15 18:56:38 -08:00
flywind
38b8d080f2 close #1550 add testcase (#16640) 2021-01-08 14:42:38 +01:00