; RED for fieldtest finding B2 (raw-buf milestone, Gitea #7). ; ; Property: a `loop` whose result is `let`-bound, and whose body ; references one of its own loop binders on the non-recur exit, must ; BUILD — not only `check`. The let-lowering in codegen calls ; `synth_arg_type` on every let value to replay its AILang type; that ; type-replay walk must descend through `Term::Loop` with the loop's ; binders in scope, exactly as it already does for `Term::Let`. ; ; The fieldtest surfaced this with an owned `RawBuf` loop binder, but ; the trigger is element-type-independent: it is the `let`-bound loop ; with a binder reference reachable through the synth body-walk. A ; plain `Int` binder is the minimal autonomous reproduction. ; ; Pre-fix symptom: `ail check` ok, `ail build` -> ; Error: module `loop_let_bound_binder_ref`: def `main`: ; unknown variable: `b` ; ; Expected stdout: 3 (loop counts i 0,1,2 and returns binder b == i). (module loop_let_bound_binder_ref (fn main (type (fn-type (params) (ret (con Unit)) (effects IO))) (params) (body (let r (loop (b (con Int) 0) (i (con Int) 0) (if (app ge i 3) b (recur (app + i 1) (app + i 1)))) (app print r)))))