✓
Passing This code compiles and runs correctly.
Code
// JS-emitter bug pin: dispatch-binding name shadows a local in the calling
// proc body, producing `const c = c;` in the inlined dispatch block — a
// ReferenceError (TDZ) at runtime in JS.
//
// The proc body has a local `c` it passes to the effect call. The dispatch
// line binds the payload to a name *also* called `c`. js_emitter inlines:
//
// const c = ...; // local from proc body
// { const c = c; ... } // BUG: inner const shadows but RHS hits TDZ
//
// Zig emits a closure-passing trampoline (`__H.key(c)`) so no inlined block,
// no collision — Zig path passes. JS path crashes.
//
// Fix shape: the JS emitter should rename the dispatch binding when it
// collides with a local at the call site, OR skip the binding emit when the
// payload expression IS the binding name (`const c = c` is a no-op).
pub event run { n: u64 }
! key u64
pub event onKey { ch: u64 }
pub event report {}
run(n: 1)
! key c |> onKey(ch: c)
report()
Actual
count=1
Expected output
✓ Zig✓ JavaScriptcount=1
Emitted JavaScript source
let count = 0;
const main_module = {
run_event: {
handler(input, H) {
const key = H.key;
const n = input.n;
for (let i = 0; i < n; i++) {
const c = 42;
key(c);
}
},
},
onKey_event: {
handler(input) {
const ch = input.ch;
count = count + 1;
},
},
report_event: {
handler(input) {
console.log("count=" + count);
},
},
flow0() {
const __arg_0 = 1;
{
const n = __arg_0;
for (let i = 0; i < n; i++) {
const c = 42;
{
{
const ch = c;
count = count + 1;
}
}
} }
},
flow1() {
{
console.log("count=" + count);
}
},
};
main_module.flow0();
main_module.flow1();
Test Configuration
MUST_RUN