✓
Passing This code compiles and runs correctly.
Code
// Test: a result-emitting step inside an effect arm's body gets its own
// result_N names — it never reuses the enclosing flow fn's counter.
//
// `produce()` binds result_0 in the flow fn. `lib/pump` carries a
// resume-valued `! tick` arm, so its invocation lowers to a Handlers_N
// struct whose methods are nested inside that flow fn — and the `stored`
// write in the arm body is itself a result-emitting step. The arm body's
// results must be scoped (or depth-indexed) so they cannot shadow the
// outer binding: Zig refuses redeclaration of `result_0` inside a nested
// fn that captures the flow scope.
//
// Surfaced by koru-libs/metal/tests/drift.k (stored inside a `frames`
// arm). The arm-body path goes through emitContinuationBody with a fresh
// `var result_counter: usize = 0` (visitor_emitter.zig ~1969/3627) while
// emitter_helpers.zig already applies depth-indexed `nested_result_{d}`
// hygiene on sibling paths.
//
// v == 0+1+2+3+4+5+6 = 21.
import std/io
import std/store
import lib/pump
std/store:new(s) { v: 0[i64] }
tor produce {}
| ok i64
| err string
proc produce|zig { return .{ .ok = 7 }; }
produce()
| ok n |> lib/pump:pump(n)
! tick i |> std/store:stored { s.v: s.v + i } -> i
| done |> std/io:print.ln("v {{ s.v:d }}")
| err e |> std/io:print.ln("err {{ e:s }}")
Supporting Files
// Cross-module arm-firer: `pump` declares a resume-valued `! tick` arm and
// its |zig proc consumes the resume. Because the arm is a real call the
// proc makes (value in, value out), callers get the Handlers_N struct path
// — the arm bodies become methods nested inside the caller's flow fn,
// which is where the result_N shadow collides.
~pub tor pump { n: i64 }
! tick i64 -> i64
| done
~proc pump|zig {
var acc: i64 = 0;
var i: i64 = 0;
while (i < n) : (i += 1) acc += tick(i);
return .{ .done = .{} };
}
Actual
v 21
Expected output
v 21
Flows
flow ~new click a branch to expand · @labels scroll to their anchor
new (s, source: v: 0[i64])
flow ~produce click a branch to expand · @labels scroll to their anchor
produce
Test Configuration
MUST_RUN
koru.json:
{
"name": "arm-body-result-shadow",
"version": "0.1.0",
"paths": {
"std": "../../../../../koru_std",
"app": "{{ ENTRY }}",
"lib": "{{ ENTRY }}/test_lib"
}
}