Files
AILang/docs/plans
Brummel 69749fc3e1 plan: mir.3a relocate consume_count into MIR, delete codegen's second uniqueness run
Executable plan for the first of two iterations delivering spec 0060's
mir.3 row. Two plan-recon passes (mode/consume/drop-placement surface +
the uniqueness-pass signature) established that the named deletion (the
second infer_module_with_cross run) depends ONLY on consume_count: all
three codegen scope-close drop sites read consume_count from
self.uniqueness, while the modes they also gate on (param_modes for the
own-param dec, scrutinee_is_owned for the match-arm dec) come from the
type, not the uniqueness pass (UniquenessInfo carries no mode). So mir.3
splits:

- mir.3a (this plan): relocate consume_count; delete the second run.
- mir.3b (next): fill MArg.mode / MTerm::Let.mode from the type modes
  and switch emit_call's anon-temp borrow-slot gate onto MArg.mode.

The split halves the change at the codebase's highest-risk surface
(RC/drop correctness, where the raw-buf leak saga lived) and makes each
half independently verifiable against the live=0 leak pins.

Design decisions locked in the plan:

- consume_count lands on a new binder-keyed MirDef.consume:
  BTreeMap<String,u32>, NOT on MArg. The recon surfaced the central
  structural tension: the drop sites key consume_count by
  (def, binder_name) — a per-binder aggregate — while the spec-sketched
  MArg.consume_count is per-arg-position and never reaches them. The
  per-def binder map matches both the UniquenessTable's own keying and
  all three binder kinds (param/let/pattern) uniformly. MArg.consume_count
  stays a mir.1 default (no consumer). Spec 0060 is updated to record
  this (Task 5).

- Source = run check's infer_module_with_cross inside lower_to_mir on
  the post-mono module (the synth_pure single-engine-re-walked pattern).
  The alternative of retaining a check-time result is blocked: check's
  uniqueness runs pre-mono and on-demand-from-codegen, never during
  check_workspace, so a retained result would miss the mono
  specialisations. cross_module_types (= codegen's module_def_ail_types,
  module->def->Type) is rebuilt in elaborate_workspace from the post-mono
  workspace.

Key safety property carried in the plan: this is a PURE RELOCATION of an
identical computation. infer_module_with_cross ran on the post-mono
module in codegen and now runs on the same post-mono module in
lower_to_mir — same function, same input, same output — so drop
placement is byte-identical. The live=0 leak pins (raw_buf_loop_no_leak,
loop_recur_heap_binder, print_no_leak) are the value-correctness gate.

Five tasks: (1) add MirDef.consume; (2) elaborate_workspace builds
cross_module_types + lower_module runs the pass and fills consume;
(3) codegen builds its (def,binder)->consume lookup from MIR, the three
drop sites read it, delete the run + field + import; (4) producer pin +
leak-pin acceptance + grep-clean; (5) record the split in spec 0060. No
new .ail fixture (producer pin reuses new_counter_user_adt.ail).
2026-05-31 19:40:54 +02:00
..