iter raw-buf.4 rawbuf-payload-termnew-desugar (DONE, drop-call deferred to .5): RawBuf works, prints 60 (refs #7)

Ships RawBuf end-to-end as a consumer of the raw-buf.3 scope-qualified
intrinsic mechanism, plus the general Term::New construction sugar.
Working subset committed; the drop-CALL ratification (no-leak) is
re-carved to raw-buf.5 (see b49f57d) — the flat drop FUNCTION ships here,
its call-insertion needs a codegen resolution mechanism.

What ships (all green):
- raw_buf kernel-tier submodule (crates/ailang-kernel/src/raw_buf/):
  RawBuf TypeDef (param-in {Int,Float,Bool}, ctor B a) + four
  (intrinsic) ops new/get/set/size. parse_raw_buf + workspace injection
  (kernel-tier auto-imported); workspace count 4 -> 5.
- 12 scope-qualified INTERCEPTS entries RawBuf_{new,get,set,size}__{Int,
  Float,Bool} + emit fns: new allocs an @ailang_rc_alloc slab
  (8-byte i64 size header + n*width element bytes), get/set
  getelementptr+load/store at offset 8 + i*width, size loads the header.
  Mechanical on the raw-buf.3 naming + bijection machinery; bijection
  green (4 markers -> 12 entries).
- Term::New desugar (crates/ailang-core/src/desugar.rs): (new T <types>
  <values>) -> (app T.new <values>), runs before check so the
  type-scoped callee flows through the raw-buf.3 scope threading to
  RawBuf_new__T; drops the NewArg::Type (element type inferred from
  use). Both codegen Term::New deferral arms removed (replaced with
  unreachable!). Ratified by new_stubt_builds_and_runs.
- Flat intrinsic-storage drop FUNCTION @drop_raw_buf_RawBuf (single
  @ailang_rc_dec on the slab), emitted for any TypeDef whose new op is
  (intrinsic)-bodied — distinguishes RawBuf (intrinsic new) from StubT
  (real-body new -> generic ADT drop).
- E2E: raw_buf_int (-> 60), raw_buf_float (-> 4.0), raw_buf_bool
  (-> 42), raw_buf_param_in_reject (param-not-in-restricted-set).

In-scope additions beyond the literal plan (both sound, ratified):
- qualify_workspace_term now normalises a monomorphic cross-module
  type-scoped callee (StubT.new) to <home>.f; without it
  new_stubt_builds_and_runs cannot build (StubT.new is monomorphic, so
  the raw-buf.3 poly-mono path mints no symbol). Same-module + polymorphic
  callees carved out.
- diagnostic-behaviour: (new T ..) missing-new-op now surfaces
  type-scoped-member-not-found (desugar runs before check, bypassing
  synth's Term::New arm); new-arg-kind-mismatch obsoleted. Two unit
  tests updated to the new behaviour. param-in reject unaffected.

The 5 .ll snapshots gained @drop_raw_buf_RawBuf (+ partial) — injecting
raw_buf emits its drop fn into every program; benign, regenerated to the
final IR. (The plan's "snapshots stay green" assumption was wrong.)

Verification (orchestrator, this session): cargo test --workspace 676
passed / 0 failed / 2 ignored. raw_buf_int_e2e prints 60; bijection,
round-trip, new_stubt, float/bool/reject all green. The raw_buf_no_leak
test is NOT in this commit — it moves to raw-buf.5 with the drop-call
resolution that makes it pass (the slab currently leaks at scope close;
tracked, fixed next iter; milestone not released until close).
This commit is contained in:
2026-05-30 00:49:51 +02:00
parent b49f57d9c6
commit 8ac8756682
23 changed files with 879 additions and 83 deletions
+2
View File
@@ -9,5 +9,7 @@
//! crate carries zero parser code.
mod kernel_stub;
mod raw_buf;
pub use kernel_stub::SOURCE as STUB_AIL;
pub use raw_buf::SOURCE as RAW_BUF_AIL;
+10
View File
@@ -0,0 +1,10 @@
//! Raw-buf submodule — the Form-A source of the `raw_buf` kernel-tier
//! base-extension module (RawBuf: a mutable indexed flat buffer of
//! primitive elements). Parsed by `ailang_surface::parse_raw_buf`,
//! round-trip-pinned by `raw_buf_module_round_trips`.
/// Source-of-truth Form-A text for the `raw_buf` kernel module.
/// Declares the `RawBuf` TypeDef (`param-in (a Int Float Bool)`) and
/// the four `(intrinsic)` ops `new`/`get`/`set`/`size`; codegen
/// supplies their bodies via the `RawBuf_op__<T>` intercept entries.
pub const SOURCE: &str = include_str!("source.ail");
@@ -0,0 +1,26 @@
(module raw_buf
(kernel)
(data RawBuf (vars a)
(doc "Mutable, indexed, fixed-size flat buffer of primitive elements. Opaque single-ctor handle; codegen intercepts emit raw alloc/load/store over an @ailang_rc_alloc slab. Element type restricted to {Int, Float, Bool} via param-in.")
(ctor B a)
(param-in (a Int Float Bool)))
(fn new
(doc "Allocate an uninitialised RawBuf of capacity n. Compiler-supplied (intrinsic) body; codegen intercept RawBuf_new__<T> emits @ailang_rc_alloc plus the i64 size header. Element bytes are uninitialised; caller must set before get.")
(type (forall (vars a) (fn-type (params (con Int)) (ret (own (con RawBuf a))))))
(params n)
(intrinsic))
(fn get
(doc "Indexed read. UB if i >= (size b); caller checks bounds via size. Compiler-supplied (intrinsic) body; codegen intercept RawBuf_get__<T> emits getelementptr plus load.")
(type (forall (vars a) (fn-type (params (borrow (con RawBuf a)) (con Int)) (ret a))))
(params b i)
(intrinsic))
(fn set
(doc "Indexed write. Linear: own in, own out. Under uniqueness in-place; under shared copy-on-write (Issue #22). Compiler-supplied (intrinsic) body; codegen intercept RawBuf_set__<T> emits getelementptr plus store.")
(type (forall (vars a) (fn-type (params (own (con RawBuf a)) (con Int) a) (ret (own (con RawBuf a))))))
(params b i v)
(intrinsic))
(fn size
(doc "Element count. Compiler-supplied (intrinsic) body; codegen intercept RawBuf_size__<T> emits a single i64 load from the slab header.")
(type (forall (vars a) (fn-type (params (borrow (con RawBuf a))) (ret (con Int)))))
(params b)
(intrinsic)))