✓
Passing This code compiles and runs correctly.
Code
// IMPLEMENTED — a NAMED payload field continues its same-named input binding.
//
// The output is a multi-field record; its `h` field names the same entity as
// the input `h`, so `h` should advance in place and `close` should use `h`.
// The other payload field (`n`) is an ordinary new binding. Today the caller
// must spend `h` and reach the handle back through the payload record `p.h`.
//
// Green: the payload field `h` continues the input `h`; `close` is rewritten
// to `close(p.h)` (output_emitted.zig).
import app/held
import std/io
app/held:open()
| opened h |> app/held:advance(h, n: 1)
| advanced p |> std/io:print.ln("advanced, n={{ p.n:d }}") |> app/held:close(h)
| err e |> std/io:print.ln("advance err: {{ e:s }}")
| err e |> std/io:print.ln("err: {{ e:s }}")
Supporting Files
// The NAMED-payload twin: `advance` re-mints <active!> on the same handle, but
// the output is a multi-field record whose `h` field names the same entity as
// the input field `h` — `window.paint { win } | painted { win, pixels }`.
const std = @import("std");
pub const Handle = struct { _token: u8 };
~pub tor open { }
| opened *Handle<open!>
| err string
~proc open|zig {
const h = std.heap.page_allocator.create(Handle) catch unreachable;
h.* = Handle{ ._token = 0 };
return .{ .opened = h };
}
~pub tor advance { h: *Handle<!open|!active>, n: i32 }
| advanced { h: *Handle<active!>, n: i32 }
| err string
~proc advance|zig {
return .{ .advanced = .{ .h = h, .n = n } };
}
~pub tor close { h: *Handle<!active> }
~proc close|zig {
std.heap.page_allocator.destroy(h);
}
Actual
advanced, n=1
Expected output
advanced, n=1
Flows
flow ~open click a branch to expand · @labels scroll to their anchor
open
Test Configuration
MUST_RUN