Files
Nim/tests/iter
metagn c06bb6cc03 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
2025-04-15 19:29:46 +02:00
..
2021-03-24 08:49:05 +01:00
2015-01-11 13:51:30 +01:00
2019-05-03 23:43:41 +02:00
2014-01-13 02:10:03 +01:00
2019-11-05 11:05:46 +01:00
2019-05-30 11:18:17 +02:00
2019-11-05 16:55:08 +01:00
2019-05-13 20:50:21 +02:00
2019-05-13 20:50:21 +02:00
2019-05-13 20:50:21 +02:00
2018-12-11 21:23:21 +01:00
2014-01-13 02:10:03 +01:00
2015-07-14 01:37:07 +02:00