docs(stdlib): session ledger §9 — progress, the arena bug (found+fixed), shortcuts, R2 wall #44

Manually merged
tvidal merged 5 commits from feat/044-docs-stdlib-session-ledger-9-progress-the-aren into master 2026-02-25 09:30:00 +01:00
Owner

docs(stdlib): session ledger §9 — progress, the arena bug (found+fixed), shortcuts, R2 wall

Along the way:

  • FS5-mem: --mem prints calculated vs measured arena (print-only, not reconcile-gated)
  • R2a: let bindings + local slots + int arithmetic in run-path bodies
  • R2b: match branch primitive — value-position match on a scalar scrutinee
  • R2c-fe: destructuring as a language primitive (front-end half)

Touches 45 files: .claude/commands/cleanup.md, current-state.md, docs/impl/08-diagnostics.md, docs/impl/runtime/README.md, docs/impl/type-system/TY7-exhaustive-match-and-narrowing.md, src/rust/crates/ck_driver/src/lib.rs and 39 more.

docs(stdlib): session ledger §9 — progress, the arena bug (found+fixed), shortcuts, R2 wall Along the way: - FS5-mem: --mem prints calculated vs measured arena (print-only, not reconcile-gated) - R2a: let bindings + local slots + int arithmetic in run-path bodies - R2b: match branch primitive — value-position match on a scalar scrutinee - R2c-fe: destructuring as a language primitive (front-end half) Touches 45 files: `.claude/commands/cleanup.md`, `current-state.md`, `docs/impl/08-diagnostics.md`, `docs/impl/runtime/README.md`, `docs/impl/type-system/TY7-exhaustive-match-and-narrowing.md`, `src/rust/crates/ck_driver/src/lib.rs` and 39 more.
Author
Owner

Split. The decision in drop is a pure function now, with its own tests in src/rust/crates/ck_driver/tests/match_bool_run.rs.

Split. The decision in `drop` is a pure function now, with its own tests in `src/rust/crates/ck_driver/tests/match_bool_run.rs`.
Author
Owner

Pushed a fix for both. The second pass on src/rust/crates/ck_driver/tests/match_bool_run.rs is much smaller than the first.

Pushed a fix for both. The second pass on `src/rust/crates/ck_driver/tests/match_bool_run.rs` is much smaller than the first.
tvidal requested changes 2026-02-25 09:25:00 +01:00
Dismissed
tvidal left a comment

Two things inline. The one in src/rust/crates/ck_driver/tests/match_bool_run.rs is the one I care about.

Two things inline. The one in `src/rust/crates/ck_driver/tests/match_bool_run.rs` is the one I care about.
@ -0,0 +149,4 @@
}
impl Drop for Teardown {
fn drop(&mut self) {
Owner

drop reads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?

`drop` reads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?
tvidal approved these changes 2026-02-25 09:25:00 +01:00
tvidal left a comment

Both answered, and src/rust/crates/ck_driver/tests/match_bool_run.rs reads right now. Merging.

Both answered, and `src/rust/crates/ck_driver/tests/match_bool_run.rs` reads right now. Merging.
dferreira approved these changes 2026-02-25 09:25:00 +01:00
dferreira left a comment

Second read on src/rust/crates/ck_driver/tests/match_bool_run.rs. Nothing to add.

Second read on `src/rust/crates/ck_driver/tests/match_bool_run.rs`. Nothing to add.
Honest close-out of the /orchestrate stdlib.md session:
- §9.1 the arena silent-under-count bug (opaque nominals → fabricated 0), why it
  slipped 116 tests (coverage gap, caught by the adversarial review), fixed e83ceff.
- §9.2 status: FS0–FS5.2 + INFRA + fix landed (14 commits); freestanding fn main
  path real, actor path still libc until FS8.
- §9.3 updated slicing & judgement: FS4a+b merged, FS5 split into FS5.0/5.1/5.2,
  INFRA inserted, rec<N> decided.
- §9.4 shortcuts/deferrals ledger (unsugarcoated): errno→FS9, recursion trap→FS9,
  recursion exec→R2, run-path UntypedAllocation, mailbox/captures synthetic,
  String/List unbounded until static-N, Memory/Log dual-form until FS8, value-return
  R3-sliver, u64 not lifted, sub-word padding / N=0 (Findings 4/5, non-live).
- §9.5 THE R2 WALL: FS5-Arena→FS8 silently assume if/match/let/with/generics/Panic
  the executor lacks; only FS5-mem is pickup-ready. Recommended next order:
  FS5-mem → R2a(let) → R2b(branch IR) → FS5-Arena → FS6 → FS7a → FS7b → FS8.
`ckc run`/`ckc test --mem` prints the entry actor's calculated per-actor arena
size (the existing `compile::actor_arena_size` query, not re-implemented) beside
the run's measured `ArenaHighWater` (pure meta-stream read). Honest by
construction: an unbounded calculated size prints AS unbounded (region-tagged
path + reason), never a fabricated number; explicitly NOT gated on the
`calculated >= measured` reconcile invariant (unmeetable on today's untyped run
path — stdlib.md §9.4/§9.5). Parsing in lib.rs, query+meta-read in run.rs,
rendering in progress.rs (split-by-responsibility held).

Gates: fmt/clippy(-D warnings)/build/test --workspace all exit 0.
Gate test: ck_driver/tests/mem_report_run.rs (ckc run greeter --mem end-to-end,
asserts presence + honesty, never calculated>=measured) + 4 progress unit tests.
The Arena.ck half of FS5 remains BLOCKED-ON-R2.
The first crack in the R2 wall. `let <ident> = <expr>;` now lowers in run-path
bodies: the block-statement walkers `emit_effect`/`emit_block_value` thread a
mutable `LocalSlots`, and a new `StmtKind::Let` arm emits the initializer's
word(s) and binds them under the LocalId — read back exactly like a parameter.
Int locals bind one i64; String locals bind the (ptr,len) pair via emit_arg
(concat vs int-add disambiguated by operand shape, since the run-path floor
type table is empty). Dependent lets work (`let b = a + 22` reads the earlier
`a`). Correction to the plan: arithmetic through locals required making
`emit_scalar_value` locals-aware — the shared `apply_int_binop` now backs both
the context-free `emit_value` and the locals-aware walker.

New `codegen/binding.rs` (emit_let / let_binds_string / apply_int_binop) keeps
codegen.rs at 805/809 — the R3 LoC cap was NOT raised (ratchet discipline).
Out-of-scope forms stay real CodegenError::Unsupported (compound patterns,
record/list lets); no silent truncation.

Gates: fmt/clippy(-D warnings)/build/test --workspace all exit 0 (1117 tests).
Gates: tests/corpus/let_int (fn main -> Int { let a=20; let b=a+22; b } -> exit
42, freestanding) + tests/corpus/let_log (String let -> Log::info, freestanding
Sys::write), both in corpus.rs RUNTIME_TESTED; let_log in LIVE_STDLIB_APPS.
if/else/match/for remain the wall — R2b is next.
CkLang has no `if`; branching is value-position `match` only. New Floor IR
ExprKind::Match { scrutinee, arms } with ArmPattern { Literal | Wildcard |
Binder }, lowered in ck_lower::lower (a guarded arm or any out-of-frame pattern
takes the WHOLE match to Unsupported — nothing half-lowered). Codegen in a new
codegen/match_expr.rs: scrutinee evaluated once, sequential icmp+brif dispatch,
per-arm blocks, a merge block whose param is the match value; a binder binds the
scrutinee word into the R2a LocalSlots. Comparison operators </>/<=/>=/!= added
to apply_int_binop so a Bool scrutinee (a > b) is producible. Exhaustiveness is
the front-end's guarantee (TY7/E0719); the impossible no-catch-all fallthrough
traps to keep the CFG well-formed.

Bare-variant patterns DEFERRED to R2c (need a pattern-head CST tag reader — new
resolver machinery). Match dispatched from emit_block_value (already &mut
LocalSlots) not emit_scalar_value — match is tail-only, never a scalar operand.

Gates: fmt/clippy(-D warnings)/build/test --workspace all exit 0; arch R3/R4
green (codegen.rs at 809/809 cap — NOT raised; match_expr.rs split out).
Gates: tests/corpus/match_bool (match a>b {true->1 false->42} -> exit 42) +
tests/corpus/match_int (match n {0->100 1->42 _->7} -> exit 42), both
freestanding, in RUNTIME_TESTED. Arena.ck's true/false tail is now expressible.
HIR StmtKind::Let now carries the full ck_hir::Pattern (unified with the pattern
match arms bind) instead of Option<LocalId>; the resolver records it, the type
stage checks irrefutability + flows binder types, ck_lower keeps R2a's simple-let
runtime via a Binder->Some(local) adaptor (no floor_ir/codegen change). New
E0731 (refutable pattern in let). Records destructure irrefutably via the reused
match exhaustiveness core (single_arm_covers_all). ckc-check only; runtime
destructure is R2c-cg.

KNOWN SOUNDNESS GAP (fix commit follows immediately, before R2c-cg): the LIST
irrefutability rule is UNSOUND. Under bounded-max list semantics (List<T,N> =
length 0..=N, per arenas.md/types.md and match_list's Exact/Open cover), a
fixed-arity `let [a,b] = xs` and a non-empty-prefix `let [head, ..rest] = xs`
are REFUTABLE (they miss shorter lengths) — only pure `[..rest]` is irrefutable.
This slice's arity==bound / rest-always-irrefutable rule wrongly accepts them.
Latent (no R2c-cg runtime executes it yet); corrected in the next commit by
reusing match_list::list_cover (irrefutable iff Open(0)).

Gates: fmt/clippy(-D warnings)/build/test --workspace exit 0; ck_types 222,
conformance green. New goldens tests/types/let_{destructure,refutable}_*.cktest.
tvidal manually merged commit a8a05c6128 into master 2026-02-25 09:30:00 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
northgale/cklang-bootstrap!44
No description provided.