100%

tests

Goal

Comprehensive while.ori spec tests with dual-execution parity, negative E0860/E0861 pins, and cross-feature interactions.

Implementation Sketch

Coverage audit against the landed test file: tests/spec/expressions/while.ori already exists at HEAD (compiler_repo commit b9939de7d) with observable assert_eq pins and #compile_fail(E0860/E0861) pins at lines 135/141/213. Audit it against the proposal’s examples + the matrix below; close any coverage gap surfaced (do NOT re-author the file); verify interpreter==LLVM parity on the full file.

Delivered State Note — verify, do not re-execute

The test deliverable substantially landed at HEAD. Execute the work items as a coverage audit + gap-closure pass against the existing file, never a fresh authoring pass.

Prerequisites (depends_on)

  • depends_on: [s-114d5c42, s-fe22c928] — walking-skeleton owns end-to-end while infrastructure (parse-desugar → typeck → canon-lower → both backends); break-continue-validation owns the E0860/E0861 typeck enforcement the #compile_fail pins assert against.
  • Record the edge via scripts/plan_corpus/write.py (plan.json is script-only per plan-read-discipline §2.1).

Section Boundary

This tests section owns the matrix-completeness coverage audit of the parity results (coverage breadth, interaction matrix, negative pins). Walking-skeleton w-67a0c093 owns the basic-skeleton parity-verification gate (the end-to-end interpreter==LLVM mechanism for the minimal while loop).

Inherited HYG Findings — map each to its closing work item

Five open HYG findings target compiler_repo/tests/spec/expressions/while.ori and fall within this section’s coverage-audit scope. Each binds to a closing work item (the dependency intent on these findings is documented here; closure status flips via the bug-tracker / hygiene-finding script path, not by editing plan.json directly per plan-read-discipline §2.1):

HYG findingConcernClosing work item
HYG-01-003Dangling test target: tests @while_is_void references a missing function; dead @while_returns_void at while.ori:56w-84b56685 (pull into the coverage audit — fix the dangling target + remove/wire the dead fn while editing while.ori)
HYG-01-004Labeled-while matrix cells absent (break:w, continue:w, E0860, E0861 not covered)w-84b56685 (named explicitly in the coverage list below)
HYG-01-009Interaction cells absent (mutable self, ? in body, match in body, closures capturing loop var)w-51b17ae9 (five-cell interaction matrix below)
HYG-01-013Weak-descriptor test namesw-84b56685 (rename to <subject>_<scenario>_<expected> shape per test-naming-lint during the audit)
HYG-3C-029Ungrounded (separately-tracked) comment claim at while.ori:171 (labeled-break/continue runtime path)w-84b56685 (the labeled-while cells audit this region — ground the claim with a concrete tracker reference or remove the unsubstantiated parenthetical)

Spec References

while-loop-proposal.md (all examples); tests.md Matrix Testing + Interaction Testing + Negative Testing.

Work Items

  • tests/spec/expressions/while.ori base-coverage audit. Cover (each asserts an observable result via assert_eq — no orphan tests per tests.md Test Hygiene):
    • basic counting loop; nested while; &&-compound condition; do-block body; do-bare-expr body.
    • labeled-while matrix cells (closes HYG-01-004): while:outer { ... break:outer } and while:outer { ... continue:outer } (valueless labeled break/continue targeting the outer while — while is void with no yield per spec 16-control-flow.md §16), plus the negative break/continue-validation cells break value#compile_fail(E0860), continue value#compile_fail(E0861), and the labeled-value negative while:outer { ... continue:outer value }#compile_fail(E0861) (continue:label value is valid only for labeled for...yield per spec §16, never a labeled while target). These pins assert break-continue-validation s-fe22c928’s typeck enforcement.
    • fix the dangling test target (closes HYG-01-003): tests @while_is_void references a missing function — wire it to a real @while_is_void body or remove the dangling tests clause; remove or wire the dead @while_returns_void at while.ori:56.
    • rename weak-descriptor test names to the <subject>_<scenario>_<expected> shape per test-naming-lint (closes HYG-01-013) during the audit edit.
    • ground the (separately-tracked) comment claim at while.ori:171 (closes HYG-3C-029): while auditing the labeled-break/continue cells, replace the unsubstantiated parenthetical with a concrete tracker reference or remove it.
    • void-typing negative pin: #compile_fail test that assigning a while loop to a non-void binding (e.g. let x: int = while c do ();) is rejected — while is void per ori-syntax.md (while condition do body type is void; no while...yield). The positive while.ori tests do not pin this negative; a regression to a non-void while would pass every existing test.
  • Dual-execution parity + non-vacuous leak gate:
    • Every while.ori test runs under interpreter (debug) AND LLVM (release) and produces identical results (per CLAUDE.md Fix Completeness).
    • ORI_CHECK_LEAKS=1 reports zero leaks. The leak gate is vacuous on primitive-only loop bodies — mandate AT LEAST ONE test that constructs a heap allocation inside the while body (e.g. building a [int] list across iterations via .push/.append, or a {K: V} map) so the leak check actually exercises loop-body ARC inc/dec on each iteration. Without a heap-allocating body the gate passes regardless of correctness.
  • Interaction matrix completeness (closes HYG-01-009; per tests.md:134 loops touching memory need ≥5 interactions, and while.ori has 0 of the named cells at HEAD). Each cell asserts an observable result AND must produce identical interpreter==LLVM output (parity per cell):
    • mutable self in body: a method whose while body mutates self — assert the mutation propagates to the caller (self mutation is observable per ori-syntax.md Impls).
    • ? in body: a while body that contains an expr? propagating Err/None — assert the loop exits on the error path AND that AIMS/ARC decrements any loop-body allocations live at the ? exit (no leak on early-exit; verify under ORI_CHECK_LEAKS=1).
    • match in body: a match expression inside the while body driving per-iteration branch behavior — assert the branch-selected value per iteration.
    • closures capturing the loop var: a closure created inside the body capturing the loop variable — assert the captured reference observes each iteration’s value at capture time (Ori captures by value per ori-syntax.md Lambdas), NOT a single initial snapshot; collect the captured values and assert_eq the per-iteration sequence.
    • fifth cell (to reach the ≥5 memory-interaction floor): while body that grows a heap collection and reads it back after the loop — doubles as the w-5e6b0905 non-vacuous-leak-gate body.