✓
Passing This code compiles and runs correctly.
Code
// REQUIREMENT (effect-branch obligations, no-escape negative — the discriminator):
// The `! each` signature carries NO `<state!>` resume, so an obligation created
// in the handler CANNOT escape the firing. Here the handler creates an `active!`
// obligation and only USES it (no discharge, no destroy event) — so it is
// unbalanced and MUST be rejected. (Mirror of old-for 330_053 on the new path.)
// If this is silently accepted, obligation tracking is NOT wired through `! each`.
~import std/build
~std/build:requires { exe.linkLibC(); }
const std = @import("std");
const Resource = struct { id: usize };
const allocator = std.heap.c_allocator;
~event create { id: usize }
| created *Resource<active!>
~proc create|zig {
const r = allocator.create(Resource) catch unreachable;
r.* = Resource{ .id = id };
return .{ .created = r };
}
~event use { r: *Resource<active> }
~proc use|zig { std.debug.print("using {}\n", .{r.id}); }
~pub event gen { n: usize }
! each usize
| done usize
~proc gen|zig {
for (0..n) |i| { each(i); }
return .{ .done = n };
}
~gen(n: 3)
! each i |> create(id: i)
| created r |> use(r)
| done _ |> _
pub fn main() void {}
Backend must reject with:
CONTAINS error[KORU030]
CONTAINS was not dischargedError Verification
Actual Compiler Output
error[KORU030]: Resource 'r' with phantom state <active!> was not discharged. No event accepts <!active>.
--> auto_discharge:33:0
❌ Compiler coordination error: Auto-discharge failed (multiple disposal options or no disposal event)
error: CompilerCoordinationFailed
/Users/larsde/src/koru/tests/regression/400_RUNTIME_FEATURES/400_103_effect_obligation_cannot_escape/backend.zig:94:13: 0x1012d64db in emit (backend)
return error.CompilerCoordinationFailed;
^
/Users/larsde/src/koru/tests/regression/400_RUNTIME_FEATURES/400_103_effect_obligation_cannot_escape/backend.zig:190:28: 0x1012d71c7 in main (backend)
const generated_code = try RuntimeEmitter.emit(compile_allocator, final_ast);
^Test Configuration
MUST_FAIL