○
Planned This feature is planned but not yet implemented.
reject redundant same-module phantom qualification (ratified design, unbuilt)
Code
// PIN (unbuilt — ratified design): a phantom state qualified with the SAME
// module its base type already names is REDUNDANT and must be REJECTED with a
// teaching diagnostic ("bare `<!active>` already scopes to the base type's
// module `app/lib/db` — drop the qualifier"). One-canonical-spelling: there is
// exactly ONE way to write "app/lib/db's active on app/lib/db's Transaction" —
// the bare form (330_087-style base-type-module self-resolution).
//
// Currently NOT built: the redundant form compiles fine (the qualified state
// resolves and unifies with the issued state), so this MUST_ERROR is RED until
// the rejection lands. Contrast 330_087 (qualifying a FOREIGN module's state on
// a primitive base — required, not redundant).
~import std/io
~import app/lib/db
// REDUNDANT: `*app/lib/db:Transaction` already names app/lib/db; re-qualifying
// the state `<app/lib/db:!active>` restates it. Should be `<!active>` (bare).
~tor finish { t: *app/lib/db:Transaction<app/lib/db:!active> }
~proc finish|zig {
return;
}
~app/lib/db:begin(): tx |> finish(t: tx) |> std/io:print.ln("ok")
Frontend must reject with:
CONTAINS redundantFlows
flow ~begin click a branch to expand · @labels scroll to their anchor
begin
Imported Files
// A module that declares a resource TYPE with intrinsic typestate. `active` is
// app/lib/db's own state, issued bare in-module (self-resolves to app/lib/db).
const std = @import("std");
const Transaction = struct { id: i32 };
~pub tor begin { } -> *Transaction<active!>
~proc begin|zig {
const t = std.heap.page_allocator.create(Transaction) catch unreachable;
t.* = .{ .id = 1 };
return t;
}