✓
Passing Passing: the compiler rejects this program as expected.
Code
// Phantom obligation carried as a RECORD FIELD. `make` returns { h: *Handle<owned!>,
// n } — an obligation riding a field alongside a plain one. RULED: a return/resume
// record field follows the SAME obligation rules as an event-payload field (which
// already carries obligations — `write { file: *File<opened>, data: string }`, 2103;
// `take { h: *Handle<!owned> }`, 330_082 — the input-side mirror of this). The
// consumer binds the record, uses `n`, and never discharges `r.h`: the field-level
// <owned!> must be caught (KORU030) exactly as a dropped whole-value obligation is
// (330_094), never lowered as raw Zig. Obligations compose into records, to and from.
~import std/io
const std = @import("std");
const Handle = struct { n: i32 };
~tor make { id: usize } -> { h: *Handle<owned!>, n: i64 }
~proc make|zig { const h = std.heap.page_allocator.create(Handle) catch unreachable; h.* = .{ .n = 5 }; return .{ .h = h, .n = 7 }; }
~tor dispose { h: *Handle<!owned> }
~proc dispose|zig { std.heap.page_allocator.destroy(h); }
~make(id: 1): r |> std/io:print.ln("n={{ r.n:d }}")
Actual compiler output
error[KORU030]: Resource 'h' obligation <owned!> was not discharged. Call one of: dispose
--> tests/regression/300_ADVANCED_FEATURES/330_PHANTOM_TYPES/330_096_obligation_in_record_field/input.kz:16:0
❌ Compiler coordination error: Auto-discharge failed (multiple disposal options or no disposal event)
(set KORU_BACKEND_TRACE=1 for the backend return trace)Compiler must reject:
Compilation must fail with a diagnostic.
Flows
flow ~make click a branch to expand · @labels scroll to their anchor
make (id: 1)
Test Configuration
MUST_ERROR