; Fieldtest raw-buf.2 (Axis 1 + Axis 4, loop-threaded owned RawBuf).
; Task: "fill a buffer of N slots with a sequence in a loop, then read it
; back and print the running maximum." This is the LLM-natural way to
; populate a buffer whose length is a runtime N rather than three literal
; (RawBuf.set buf <lit> ...) lines: thread the owned buffer through a
; (loop ...) / recur, one RawBuf.set per iteration.
;
; The whole program is inlined into main (no borrow-mode helper, which
; rawbuf_1_score_table.ail showed is rejected). The fill loop threads the
; owned `b` through recur; the read loop drives off RawBuf.size.
;
; Expected stdout: 16  (slots 1,4,9,16; running max ends at 16).
;
; This was the fieldtest repro for B2 (#47): `ail check` passed but
; `ail build` FAILED at codegen with `unknown variable: b` — the synth
; type-replay walked the `loop` body without the loop binders in scope.
; Now fixed: the replay descends through `loop` with its binders bound.
; OUTCOME (current): checks, builds, runs; prints 16. Leak-clean under
; AILANG_RC_STATS (the loop-threaded owned buffer drops at scope close,
; B5 — the let-bound loop result is now registered for scope-close drop).

(module rawbuf_2_running_max
  (fn main
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let buf (new RawBuf (con Int) 4)
        (let filled
          (loop (b (con RawBuf (con Int)) buf) (i (con Int) 0)
            (if (app ge i 4)
                b
                (recur (app RawBuf.set b i (app * (app + i 1) (app + i 1)))
                       (app + i 1))))
          (app print
            (loop (mx (con Int) 0) (i (con Int) 0)
              (if (app ge i (app RawBuf.size filled))
                  mx
                  (recur (if (app gt (app RawBuf.get filled i) mx)
                             (app RawBuf.get filled i)
                             mx)
                         (app + i 1))))))))))
