Files
AILang/examples/print_eq_arg_repro.ail
T
Brummel 1fb225ee25 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.
2026-05-14 01:38:41 +02:00

7 lines
1022 B
Plaintext

(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)))))