bugfix: mono cursor misalignment at poly-free-fn Var with class-constrained Forall
When `synth` visits a `Term::Var v` where v is a polymorphic free fn whose `Type::Forall` carries class constraints (e.g. `print : forall a. Show a => ...`, `lt`/`le`/`gt`/`ge : forall a. Ord a => ...`), it pushes BOTH a class `ResidualConstraint` for each constraint AND a `FreeFnCall` observation at the same Var site. The mono walkers (`interleave_slots` collection-side and `rewrite_mono_calls` rewrite-side) consumed only ONE slot per such Var, leaving the class-residual cursor misaligned for every subsequent class-method call in the same body. The next `eq`/`compare` Var in the body then consumed the leftover `Show T` / `Ord T` slot and was mis-rewritten — codegen reported `call prelude.show__Bool arg type mismatch: expected i1, got i64` (or the Int dual). Fix: new `poly_free_fn_constraint_counts_for_module` registry in mono.rs (sibling to `poly_free_fn_names_for_module`) maps each synth-visible poly-free-fn name to its declared constraint count. Threaded into `collect_residuals_ordered`, `interleave_slots`, and `rewrite_mono_calls`. Both walkers now advance the cursor by 1 + N (FreeFn slot + N class-residual fillers) at every poly-free-fn Var. RED test `print_with_class_method_arg_does_not_misalign_mono_cursor` (crates/ail/tests/show_print_e2e.rs) + fixture examples/print_eq_arg_repro.ail pin the bug — body `(app print (app eq 1 2))` previously crashed at codegen, now prints "false". Bug surfaced 2026-05-14 during the rpe.1 BLOCKED orchestrator run; existed in latent form since iter 24.3 (the poly-free-fn-with-class- constraint synth shape was new there). No schema / codegen / DESIGN.md changes. cargo test --workspace: 564 / 0 / 3.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
(module print_eq_arg_repro
|
||||
(fn main
|
||||
(doc "RED-pin fixture for the iter 24.3 cursor-misalignment bug. `(app print <arg>)` where `<arg>` itself contains a class-method call (here `eq`) causes the mono-rewrite cursor to consume the `Show T` residual pushed by `print`'s poly-free-fn observation as if it were the slot for the inner class method. Result: the inner `eq` Var is rewritten to `prelude.show__Bool` instead of `prelude.eq__Int`, and codegen reports `call prelude.show__Bool arg type mismatch: expected i1, got i64`. Bug surfaced 2026-05-14 during the rpe.1 BLOCKED orchestrator run; root cause is `crates/ailang-check/src/mono.rs::interleave_slots` not advancing the class-residual cursor when visiting a poly-free-fn Var whose source `Type::Forall` carries a class constraint. Fixture pinned by `print_with_class_method_arg_does_not_misalign_mono_cursor` in crates/ail/tests/show_print_e2e.rs.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app eq 1 2)))))
|
||||
Reference in New Issue
Block a user