Skip to content

for loops over .passive iterators: three fixes, no new protocol for now - #2570

Closed
Araq wants to merge 1 commit into
masterfrom
araq-passive-fixes
Closed

Araq wants to merge 1 commit into
masterfrom
araq-passive-fixes

Conversation

@Araq

@Araq Araq commented Sep 22, 2026

Copy link
Copy Markdown
Member

No description provided.

The corofor trampoline stays what it is — a loop inside one state proc,
driven by `advance` — and keeps `.closure` iterators' arrangement:

- A loop in a `.passive` routine did not compile: `trGoto` took the
  iterator call for a suspension point of the enclosing routine and put a
  state boundary inside the loop. `corofor` is its own case there now, and
  the iterator call is not walked as one. `trCoroFor` also runs the call's
  arguments through `coroTr`, so `(haddr x)` names the loop variable's
  frame field rather than a local that no longer exists.
- The "did it yield?" test was frame identity (`it.env == myEnv`), which a
  passive proc the iterator called satisfies by returning into that same
  frame: the body ran again with the previous value (`yield 1; step();
  yield 2` printed 1 1 2). `yield` sets `CoroutineBase.yielded` and the
  loop tests and clears it (`iterYielded`). Costs 8 bytes per frame — the
  tpassivespawn valgrind golden moves 360 -> 432 bytes for its 9 frames.
- A park was treated as the iterator's end: the loop stopped and its
  `finally` cancelled a frame the I/O ring still owned. The loop cannot
  wait for a park — it and the frame are driven from one stack — so
  `iterStopped` says so instead of ending quietly.

A body that would need to suspend (a passive call, a `yield`) is refused
with a message for the same reason; a NESTED for loop is not one of those.

Also: a `{.cast(...)}:` block anywhere in a coroutine crashed hexer —
`trGoto` flattened the pragma block's single body into several statements.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

proc step() {.passive.} = discard

iterator count(n: int): int {.passive.} =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it cannot suspend what is difference between simple iterators and passive iterators?

@Araq Araq closed this Sep 23, 2026
@Araq
Araq deleted the araq-passive-fixes branch September 23, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants