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_failpins 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 finding | Concern | Closing work item |
|---|---|---|
| HYG-01-003 | Dangling test target: tests @while_is_void references a missing function; dead @while_returns_void at while.ori:56 | w-84b56685 (pull into the coverage audit — fix the dangling target + remove/wire the dead fn while editing while.ori) |
| HYG-01-004 | Labeled-while matrix cells absent (break:w, continue:w, E0860, E0861 not covered) | w-84b56685 (named explicitly in the coverage list below) |
| HYG-01-009 | Interaction cells absent (mutable self, ? in body, match in body, closures capturing loop var) | w-51b17ae9 (five-cell interaction matrix below) |
| HYG-01-013 | Weak-descriptor test names | w-84b56685 (rename to <subject>_<scenario>_<expected> shape per test-naming-lint during the audit) |
| HYG-3C-029 | Ungrounded (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.oribase-coverage audit. Cover (each asserts an observable result viaassert_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 }andwhile:outer { ... continue:outer }(valueless labeled break/continue targeting the outer while —whileis void with no yield per spec 16-control-flow.md §16), plus the negative break/continue-validation cellsbreak value→#compile_fail(E0860),continue value→#compile_fail(E0861), and the labeled-value negativewhile:outer { ... continue:outer value }→#compile_fail(E0861)(continue:label valueis valid only for labeledfor...yieldper spec §16, never a labeledwhiletarget). These pins assert break-continue-validations-fe22c928’s typeck enforcement. - fix the dangling test target (closes HYG-01-003):
tests @while_is_voidreferences a missing function — wire it to a real@while_is_voidbody or remove the danglingtestsclause; remove or wire the dead@while_returns_voidatwhile.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 atwhile.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_failtest that assigning awhileloop to a non-void binding (e.g.let x: int = while c do ();) is rejected —whileis void per ori-syntax.md (while condition do bodytype isvoid; nowhile...yield). The positivewhile.oritests do not pin this negative; a regression to a non-voidwhilewould pass every existing test.
- basic counting loop; nested while;
- Dual-execution parity + non-vacuous leak gate:
- Every
while.oritest runs under interpreter (debug) AND LLVM (release) and produces identical results (per CLAUDE.md Fix Completeness). ORI_CHECK_LEAKS=1reports 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.
- Every
- Interaction matrix completeness (closes HYG-01-009; per tests.md:134 loops touching memory need ≥5 interactions, and
while.orihas 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
whilebody mutatesself— assert the mutation propagates to the caller (self mutation is observable per ori-syntax.md Impls). ?in body: a while body that contains anexpr?propagatingErr/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 underORI_CHECK_LEAKS=1).- match in body: a
matchexpression 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_eqthe 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.
- mutable self in body: a method whose