iter revert: back out the Iteration-discipline milestone (it.1 + it.2)
One forward iteration; main never rewound.1ff7e81(the pre-9973546 commit) is the per-region byte oracle — every reverted source/test file is byte-identical to it; crates/ailang-check/src/lib.rs fully so. Root cause being corrected: the Iteration-discipline milestone was an over-escalation of fieldtest finding F1 (a [friction] item whose own minimal recommendation was a DESIGN.md note). Its totality dichotomy made the maximally-LLM-natural build(d:Int)=Node(1,build(d-1), build(d-1)) inexpressible (it.3 BLOCKED); the only in-thesis escape (A1/it.2b) conceded the language's first documented-unenforced totality precondition — a purity-pillar dilution the user rejected in favour of a full revert + rebuild. Removed: Term::Loop/Term::Recur/LoopBinder; the verify_structural_ recursion guardedness pass + term_contains_loop + Diverge-injection + the transitively-it.2 module_fns plumbing; the five Recur*/ NonStructuralRecursion CheckError variants (+ code() + the 3 dedicated ctx() arms); the it.1 codegen loop-header/phi/back-edge + parallel block_terminated setter; all Loop/Recur walker arms; 16 it.1/it.2 fixtures; 2 pin files; bench/it3-oracle/. Restored: 2 RC fixtures to1ff7e81content. Surgically kept (not in1ff7e81, landed with the milestone but independently sound): feature-acceptance clause 3 in DESIGN.md and skills/brainstorm/SKILL.md, with its worked example de-claimed from "shipped" to hypothetical-illustration form; the F3 P2 todo. bench/orchestrator-stats/2026-05-15-iter-it.{1,2,3}.json kept as historical record (like journals/plans). Sole net addition: an honest F1/F4 documented-idiom note in DESIGN.md (the tail-recursive accumulator fallback; examples/mut_counter.ail), guarded by a doc-presence test — "a documentation note is not a reshape", asserts nothing at the typecheck level. Roadmap: the Iteration-discipline block + blocking-fork section removed; the genuine total-Int-recursion ambition preserved as a deferred P2 milestone sequenced behind a future Nat/refinement-types milestone (not abandoned — correctly sequenced after the type machinery it needs). 2026-05-15-iteration-discipline.md carries a superseded header; it.1/it.2/it.3 journals + plans stay as history. Correctness gate PRISTINE: 164 surviving 1ff7e81-era fixtures ail check/ail run byte-identical to pre-milestone behaviour (verified against a1ff7e81worktree reference compiler, zero drift); cargo test --workspace 600/0; zero residual it.1/it.2 production surface. Spec docs/specs/2026-05-16-iteration-discipline-revert.md (b3853bf), plan docs/plans/2026-05-16-iter-revert.md (abf0013).
This commit is contained in:
@@ -144,12 +144,6 @@ impl<'a> Emitter<'a> {
|
||||
let saved_mut_allocas = std::mem::take(&mut self.mut_var_allocas);
|
||||
let saved_pending_allocas = std::mem::take(&mut self.pending_entry_allocas);
|
||||
let saved_entry_marker = self.entry_block_end_marker.take();
|
||||
// Iter it.1: a `loop` inside a lambda body scopes its header /
|
||||
// phis to the closure's own body, not the outer fn's. Save and
|
||||
// reset `loop_frames` (the exact mut.3 analogue to
|
||||
// `mut_var_allocas` above) so a `Term::Recur` inside the thunk
|
||||
// cannot back-edge to an outer fn's loop header.
|
||||
let saved_loop_frames = std::mem::take(&mut self.loop_frames);
|
||||
// Iter 18d.4 fix: a lambda thunk is its own fn frame for
|
||||
// param-mode lookup. The outer fn's params are not in scope
|
||||
// inside the thunk; the thunk's own params are pushed below
|
||||
@@ -264,7 +258,6 @@ impl<'a> Emitter<'a> {
|
||||
self.mut_var_allocas = saved_mut_allocas;
|
||||
self.pending_entry_allocas = saved_pending_allocas;
|
||||
self.entry_block_end_marker = saved_entry_marker;
|
||||
self.loop_frames = saved_loop_frames;
|
||||
|
||||
// 3. Emit allocation + capture filling + closure-pair packing
|
||||
// in the OUTER body. Captures use 8 bytes each; closure-pair
|
||||
@@ -512,27 +505,6 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
Self::collect_captures(value, bound, captures, captures_set, builtins, top_level);
|
||||
}
|
||||
// Iter it.1: loop binder names bind inside the body and
|
||||
// later binder inits — they are NOT captures, mirroring
|
||||
// the `Term::Mut` arm above. Recur args are uses.
|
||||
Term::Loop { binders, body } => {
|
||||
let mut newly_bound: Vec<String> = Vec::new();
|
||||
for b in binders {
|
||||
Self::collect_captures(&b.init, bound, captures, captures_set, builtins, top_level);
|
||||
if bound.insert(b.name.clone()) {
|
||||
newly_bound.push(b.name.clone());
|
||||
}
|
||||
}
|
||||
Self::collect_captures(body, bound, captures, captures_set, builtins, top_level);
|
||||
for n in newly_bound {
|
||||
bound.remove(&n);
|
||||
}
|
||||
}
|
||||
Term::Recur { args } => {
|
||||
for a in args {
|
||||
Self::collect_captures(a, bound, captures, captures_set, builtins, top_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user