iter form-a.1 (Tasks 1-5): additive phase + relocation

First half of the form-a-default-authoring milestone-close iter
(Boss-decided strategy C, big-bang). All five tasks DONE; cargo
test --workspace green at every per-task boundary.

T1 — Add three new tests:
- parse_is_deterministic_over_every_ail_fixture (round_trip.rs)
- cli_parse_then_render_then_parse_is_idempotent (roundtrip_cli.rs)
- carve_out_inventory.rs (new file; #[ignore]'d until T8 deletion)

T2 — Bulk-render the 99 missing examples/<stem>.ail files via
`ail render`. Corpus 58 .ail (pre-iter) -> 157 .ail. Eight .ail.json
carve-outs (7 §C4(a) subject-matter + 1 §C4(b) prelude) preserved.
One re-loop triggered: load_workspace prefers .ail siblings since
ext-cli.1, so the newly-rendered imports broke seven Group-A entries
whose JSON entry-paths now resolved imports to fresh .ail. Repair:
pre-emptive forward-pull of five T3 migrations + 4 transient
#[ignore]s on workspace.rs mod tests (cleanly relocated in T5).

T3 — 14 Group-A test files migrated from ailang_core::load_workspace
to ailang_surface::load_workspace + .ail paths. Carve-out lines
preserved verbatim (7 sites in typeclass_22b2.rs / typeclass_22b3.rs).

T4 — 12 Group-B test files: bulk regex flip on build_and_run /
build_and_run_with_alloc / build_and_run_with_rc_stats call sites
(~70 e2e.rs invocations + 11 subprocess sites). Four files
mis-classified Group-A as Group-B in plan recon (mono_hash_stability,
prelude_free_fns, print_mono_body_shape, show_mono_synthesis); two
files mis-classified Group-B as Group-A (mono_recursive_fn,
mono_xmod_qualified_ref). Migrated per actual shape, not plan label.

T5 — Relocated #[cfg(test)] mod tests from production source to
integration test crates with ailang-surface dev-dependency:
- crates/ailang-core/tests/hash_pin.rs (10 tests from hash.rs)
- crates/ailang-core/tests/workspace_pin.rs (10 non-carve-out tests
  from workspace.rs)
- crates/ailang-codegen/tests/eq_primitives_pin.rs (3 tests from
  codegen/src/lib.rs:3717-3799)
- ailang-prose/tests/snapshot.rs migrated (helper + 8 fixtures) to
  .ail + ailang_surface::load_module
Carve-out tests in workspace.rs mod tests preserved in-place
(3× 22b2 + 3× ct1 = 6 tests). Tempdir-based loader-mechanism tests
(3 sites) also preserved — they don't consume examples/.

Tests: 560 passed, 0 failed, 4 ignored (was 558 + 3 T1 new -
1 transit carve_out_inventory #[ignore] = 560 active).

Tasks 6-12 (bench-driver suffix flips, e2e diff-test rewrite + 4
additional raw-JSON-inspect handlers, .ail.json deletion, retiring
obsolete roundtrip tests + schema_coverage corpus flip, §C3
DESIGN.md restatement, §A4 doctrine edits, WhatsNew + roadmap
strike) ship in the next dispatch on this iter ID.

Known debt inherited to T6-12: 4 raw-JSON-inspect tests in e2e.rs
(borrow_own_demo / reuse_as_demo / render_parse_round_trip_canonical
/ ail_run_accepts_ail_source_with_same_stdout_as_ail_json dual-form
smoke) need rewrite or #[ignore] before T8 deletion; recorded in
journal Concerns + Known debt sections.
This commit is contained in:
2026-05-13 11:12:48 +02:00
parent 1a065b37f1
commit 77b28ad64d
142 changed files with 2314 additions and 840 deletions
+23
View File
@@ -0,0 +1,23 @@
(module bench_mono_dispatch
(class Foo
(param a)
(method foo
(type (fn-type (params a) (ret (con Int))))))
(instance
(class Foo)
(type (con Int))
(method foo
(body (lam (params (typed x a)) (ret (con Int)) (body (app + (app * x 1103515245) 12345))))))
(class Looper
(param a)
(method loop_call
(type (fn-type (params a (con Int)) (ret (con Int))))))
(instance
(class Looper)
(type (con Int))
(method loop_call
(body (lam (params (typed i a) (typed acc (con Int))) (ret (con Int)) (body (if (app == i 0) acc (tail-app loop_call (app - i 1) (app + acc (app foo (app + acc i))))))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app loop_call 100000000 0)))))
+6
View File
@@ -0,0 +1,6 @@
(module bool_to_str_drop_rc
(fn main
(doc "Iter 24.1: pin that `bool_to_str` participates in RC discipline. Bind the heap-Str result to `s`, consume `s` once in `io/print_str`, let the binder drop at scope close. Under --alloc=rc with AILANG_RC_STATS=1 the atexit summary must report allocs == 1 && frees == 1 && live == 0 — the heap-Str slab allocated by str_alloc inside ailang_bool_to_str rides the same rc_header + ailang_rc_dec path as int_to_str.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s (app bool_to_str true) (do io/print_str s)))))
+6
View File
@@ -0,0 +1,6 @@
(module bool_to_str_smoke_false
(fn main
(doc "Iter 24.1: stdout-smoke for the false branch of bool_to_str. Stdout must be `false\\n` (puts adds the newline). Companion of bool_to_str_drop_rc.ail.json (which covers the true branch and the RC-stats invariant).")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s (app bool_to_str false) (do io/print_str s)))))
+11
View File
@@ -0,0 +1,11 @@
(module closure
(fn apply
(doc "apply a fn-of-Int to an Int")
(type (fn-type (params (fn-type (params (con Int)) (ret (con Int))) (con Int)) (ret (con Int))))
(params f x)
(body (app f x)))
(fn main
(doc "captures `n` from the enclosing let, returns 42")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let n 3 (do io/print_int (app apply (lam (params (typed x (con Int))) (ret (con Int)) (body (app + x n))) 39))))))
+11
View File
@@ -0,0 +1,11 @@
(module cmp_max_smoke
(fn cmp_max
(type (forall (vars a) (constraints (constraint prelude.Ord a)) (fn-type (params a a) (ret a))))
(params x y)
(body (match (app compare x y)
(case (pat-ctor LT) y)
(case _ x))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app cmp_max 3 7)))))
+32
View File
@@ -0,0 +1,32 @@
(module compare_primitives_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (match (app compare 1 2)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare 1 1)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare 2 1)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare false true)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare false false)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare true false)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare "a" "b")
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (seq (do io/print_int (match (app compare "a" "a")
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))) (do io/print_int (match (app compare "b" "a")
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))))))))))))))
+5
View File
@@ -0,0 +1,5 @@
(module ctt2_collision_cls
(class MyC
(param a)
(method op
(type (fn-type (params a) (ret (con Int)))))))
+9
View File
@@ -0,0 +1,9 @@
(module ctt2_collision_lib
(import ctt2_collision_cls)
(data Foo
(ctor MkLib))
(instance
(class ctt2_collision_cls.MyC)
(type (con Foo))
(method op
(body (lam (params (typed _x (con Foo))) (ret (con Int)) (body 2))))))
+10
View File
@@ -0,0 +1,10 @@
(module ctt2_collision_main
(import ctt2_collision_cls)
(import ctt2_collision_lib)
(data Foo
(ctor MkMain))
(instance
(class ctt2_collision_cls.MyC)
(type (con Foo))
(method op
(body (lam (params (typed _x (con Foo))) (ret (con Int)) (body 1))))))
+5
View File
@@ -0,0 +1,5 @@
(module eq_float_noinstance
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app eq 1.0 2.0) 1 0)))))
+10
View File
@@ -0,0 +1,10 @@
(module eq_ord_polymorphic
(fn at_most
(doc "Composition of prelude `gt` with `not` — semantically equivalent to `le`. Used to exercise polymorphic-helper-over-prelude-fns composition through the unified mono pass.")
(type (forall (vars a) (constraints (constraint prelude.Ord a)) (fn-type (params (borrow a) (borrow a)) (ret (con Bool)))))
(params x y)
(body (app not (app gt x y))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (if (app at_most 3 5) 1 0)) (seq (do io/print_int (if (app at_most true false) 1 0)) (do io/print_int (if (app at_most "abc" "abd") 1 0)))))))
+24
View File
@@ -0,0 +1,24 @@
(module eq_ord_user_adt
(data IntBox
(doc "A one-field box around an Int, used to demonstrate that the unified mono pass synthesises eq__IntBox from a user-written instance, not from the primitive == operator.")
(ctor MkIntBox (con Int)))
(instance
(class prelude.Eq)
(type (con IntBox))
(doc "Eq IntBox by structural unwrap of the inner Int.")
(method eq
(body (lam (params (typed a (con IntBox)) (typed b (con IntBox))) (ret (con Bool)) (body (match a
(case (pat-ctor MkIntBox ai) (match b
(case (pat-ctor MkIntBox bi) (app == ai bi))))))))))
(instance
(class prelude.Ord)
(type (con IntBox))
(doc "Ord IntBox by delegating to Int's compare on the inner field.")
(method compare
(body (lam (params (typed a (con IntBox)) (typed b (con IntBox))) (ret (con prelude.Ordering)) (body (match a
(case (pat-ctor MkIntBox ai) (match b
(case (pat-ctor MkIntBox bi) (app compare ai bi))))))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (if (app eq (term-ctor IntBox MkIntBox 3) (term-ctor IntBox MkIntBox 3)) 1 0)) (do io/print_int (if (app eq (term-ctor IntBox MkIntBox 3) (term-ctor IntBox MkIntBox 5)) 1 0))))))
+10
View File
@@ -0,0 +1,10 @@
(module eq_primitives_smoke
(fn to_int
(doc "1 if the bool is true, 0 otherwise. Used to render Eq results as printable Ints.")
(type (fn-type (params (con Bool)) (ret (con Int))))
(params b)
(body (if b 1 0)))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (app to_int (app eq 7 7))) (seq (do io/print_int (app to_int (app eq 7 8))) (seq (do io/print_int (app to_int (app eq true true))) (seq (do io/print_int (app to_int (app eq true false))) (seq (do io/print_int (app to_int (app eq "hello" "hello"))) (do io/print_int (app to_int (app eq "hello" "world")))))))))))
+6
View File
@@ -0,0 +1,6 @@
(module float_to_str_smoke
(fn main
(doc "Iter hs.4: smoke pin for the float_to_str heap-Str builtin. `do io/print_str(float_to_str(3.5))` builds through the whole pipeline (checker resolves float_to_str:(Float)->Str, codegen lowers to call ptr @ailang_float_to_str(double 3.5), runtime/str.c's ailang_float_to_str snprintfs into a heap-Str slab via libc %g, io/print_str's @puts prints from the bytes pointer at offset 8). The exact rendering of 3.5 is libc-target-dependent; on the dev target's clang+glibc with default C locale it is the three bytes `3.5`. Single-value smoke; NaN / +Inf / -Inf edge cases are deferred per the hs.4 plan.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_str (app float_to_str 3.5)))))
+5
View File
@@ -0,0 +1,5 @@
(module floats
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_float (app + 1.5 2.5)) (seq (do io/print_float (app int_to_float 42)) (do io/print_float (app neg 1.5)))))))
+5
View File
@@ -0,0 +1,5 @@
(module ge_at_int_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app ge 3 5) 1 0)))))
+5
View File
@@ -0,0 +1,5 @@
(module gt_at_bool_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app gt true false) 1 0)))))
@@ -0,0 +1,6 @@
(module heap_str_repeated_print_borrow
(fn main
(doc "Iter eob.1: heap-Str passed to io/print_str twice in sequence. Under the new rule (Term::Do args = Borrow), the second call no longer triggers use-after-consume; the linearity check accepts the program. Under --alloc=rc + AILANG_RC_STATS=1 the slab allocates once and is freed once at scope close (allocs == 1, frees == 1, live == 0).")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s (app int_to_str 42) (seq (do io/print_str s) (do io/print_str s))))))
+15
View File
@@ -0,0 +1,15 @@
(module hof
(fn inc
(doc "increment by one")
(type (fn-type (params (con Int)) (ret (con Int))))
(params x)
(body (app + x 1)))
(fn apply
(doc "apply a fn-of-Int to an Int")
(type (fn-type (params (fn-type (params (con Int)) (ret (con Int))) (con Int)) (ret (con Int))))
(params f x)
(body (app f x)))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app apply inc 41)))))
+6
View File
@@ -0,0 +1,6 @@
(module int_to_print_int_borrow
(fn main
(doc "Iter eob.1: primitive Int passed to io/print_int. The rule that Term::Do args are Borrow has no observable RC effect here because Int is unboxed; the test pins that no spurious bookkeeping appears (allocs == 0, frees == 0, live == 0).")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let n 7 (do io/print_int n)))))
+6
View File
@@ -0,0 +1,6 @@
(module int_to_str_drop_rc
(fn main
(doc "Iter hs.4: pin that `int_to_str` participates in RC discipline. Bind the heap-Str result to `s`, consume `s` once in `io/print_str`, let the binder drop at scope close. Under --alloc=rc with AILANG_RC_STATS=1 the atexit summary must report allocs == frees && live == 0 — the heap-Str slab allocated by str_alloc inside ailang_int_to_str rides the same rc_header + ailang_rc_dec path as any other RC value.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s (app int_to_str 42) (do io/print_str s)))))
+6
View File
@@ -0,0 +1,6 @@
(module int_to_str_smoke
(fn main
(doc "Iter hs.4: smoke pin for the int_to_str heap-Str builtin. `do io/print_str(int_to_str(42))` builds through the whole pipeline (checker resolves int_to_str:(Int)->Str, codegen lowers to call ptr @ailang_int_to_str(i64 42), runtime/str.c's ailang_int_to_str snprintfs into a heap-Str slab, io/print_str's @puts prints from the bytes pointer at offset 8). Single-value smoke; the spec's broader edge-case sweep (0, -1, i64::MAX, i64::MIN) is deferred to a follow-up tidy iter per the hs.4 plan.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_str (app int_to_str 42)))))
+5
View File
@@ -0,0 +1,5 @@
(module le_at_str_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app le "abc" "abd") 1 0)))))
+17
View File
@@ -0,0 +1,17 @@
(module list
(data IntList
(doc "Einfach verkettete Int-Liste, boxed.")
(ctor Nil)
(ctor Cons (con Int) (con IntList)))
(fn sum_list
(doc "Summiert die Elemente einer Int-Liste rekursiv.")
(type (fn-type (params (con IntList)) (ret (con Int))))
(params xs)
(body (match xs
(case (pat-ctor Nil) 0)
(case (pat-ctor Cons h t) (app + h (app sum_list t))))))
(fn main
(doc "Baut [10, 20, 12] und druckt die Summe (42).")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let xs (term-ctor IntList Cons 10 (term-ctor IntList Cons 20 (term-ctor IntList Cons 12 (term-ctor IntList Nil)))) (do io/print_int (app sum_list xs))))))
+24
View File
@@ -0,0 +1,24 @@
(module list_map
(data IntList
(doc "Singly-linked list of Int, boxed.")
(ctor Nil)
(ctor Cons (con Int) (con IntList)))
(fn map_int
(doc "Apply f to every element. Recursive on the tail.")
(type (fn-type (params (fn-type (params (con Int)) (ret (con Int))) (con IntList)) (ret (con IntList))))
(params f xs)
(body (match xs
(case (pat-ctor Nil) (term-ctor IntList Nil))
(case (pat-ctor Cons h t) (term-ctor IntList Cons (app f h) (app map_int f t))))))
(fn print_list
(doc "Print each Int on its own line.")
(type (fn-type (params (con IntList)) (ret (con Unit)) (effects IO)))
(params xs)
(body (match xs
(case (pat-ctor Nil) (lit-unit))
(case (pat-ctor Cons h t) (seq (do io/print_int h) (app print_list t))))))
(fn main
(doc "Build [1,2,3], double each, print result.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let xs (term-ctor IntList Cons 1 (term-ctor IntList Cons 2 (term-ctor IntList Cons 3 (term-ctor IntList Nil)))) (app print_list (app map_int (lam (params (typed x (con Int))) (ret (con Int)) (body (app * x 2))) xs))))))
+5
View File
@@ -0,0 +1,5 @@
(module lt_at_int_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app lt 3 5) 1 0)))))
+14
View File
@@ -0,0 +1,14 @@
(module max3
(fn max
(type (fn-type (params (con Int) (con Int)) (ret (con Int))))
(params a b)
(body (if (app > a b) a b)))
(fn max3
(doc "Demonstriert verschachteltes if (statt max-call) zum Test des Block-Trackings.")
(type (fn-type (params (con Int) (con Int) (con Int)) (ret (con Int))))
(params a b c)
(body (if (app > a b) (if (app > a c) a c) (if (app > b c) b c))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app max3 3 17 9)))))
+17
View File
@@ -0,0 +1,17 @@
(module maybe_int
(data Maybe (vars a)
(doc "Optional value with a polymorphic payload.")
(ctor None)
(ctor Some a))
(fn or_else
(doc "Returns the wrapped Int for Some(x) and the default d for None.")
(type (fn-type (params (con Maybe (con Int)) (con Int)) (ret (con Int))))
(params m d)
(body (match m
(case (pat-ctor None) d)
(case (pat-ctor Some x) x))))
(fn main
(doc "Print or_else for both arms; expected 7 then 99.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (app or_else (term-ctor Maybe Some 7) 99)) (do io/print_int (app or_else (term-ctor Maybe None) 99))))))
+12
View File
@@ -0,0 +1,12 @@
(module mono_hash_pin_smoke
(fn ord_to_int
(type (fn-type (params (con prelude.Ordering)) (ret (con Int))))
(params o)
(body (match o
(case (pat-ctor LT) -1)
(case (pat-ctor EQ) 0)
(case (pat-ctor GT) 1))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_bool (app eq 1 1)) (seq (do io/print_bool (app eq true true)) (seq (do io/print_bool (app eq "a" "a")) (seq (do io/print_int (app ord_to_int (app compare 1 2))) (seq (do io/print_int (app ord_to_int (app compare false true))) (do io/print_int (app ord_to_int (app compare "a" "b")))))))))))
+7
View File
@@ -0,0 +1,7 @@
(module mq1_xmod_constraint_class
(import mq1_xmod_constraint_class_dep)
(fn useShow
(doc "Positive mq.1 fixture: a polymorphic fn that takes a single value and a Show constraint, ignores the value, and returns Unit. Exercises the qualified `Constraint.class` shape end-to-end (loader + validator + check_workspace).")
(type (forall (vars a) (constraints (constraint mq1_xmod_constraint_class_dep.Show a)) (fn-type (params (borrow a)) (ret (con Unit)))))
(params _x)
(body (lit-unit))))
@@ -0,0 +1,5 @@
(module mq1_xmod_constraint_class_dep
(class Show
(param a)
(method show
(type (fn-type (params a) (ret (con Str)))))))
+8
View File
@@ -0,0 +1,8 @@
(module mq3_class_eq_vs_fn_eq
(import mq3_class_eq_vs_fn_eq_classmod)
(import mq3_class_eq_vs_fn_eq_fnmod)
(fn main
(doc "mq.3.6 fixture (c): bare `myeq 1 2` in a workspace with `class MyEq` (in classmod) and `fn myeq` (in fnmod) both imported. Fn wins per lookup precedence; the typechecker emits `class-method-shadowed-by-fn` warning so the LLM-author sees the shadow.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_bool (app myeq 1 2)))))
@@ -0,0 +1,10 @@
(module mq3_class_eq_vs_fn_eq_classmod
(class MyEq
(param a)
(method myeq
(type (fn-type (params (borrow a) (borrow a)) (ret (con Bool))))))
(instance
(class MyEq)
(type (con Int))
(method myeq
(body (lam (params (typed x (con Int)) (typed y (con Int))) (ret (con Bool)) (body true))))))
+6
View File
@@ -0,0 +1,6 @@
(module mq3_class_eq_vs_fn_eq_fnmod
(fn myeq
(doc "mq.3.6 fixture (c) helper: free fn `myeq` that shadows the class method `myeq` declared in `mq3_class_eq_vs_fn_eq_classmod`. Always returns false so the fn-wins precedence is observable at runtime if the e2e test ever runs the binary.")
(type (fn-type (params (borrow (con Int)) (borrow (con Int))) (ret (con Bool))))
(params x y)
(body false)))
+8
View File
@@ -0,0 +1,8 @@
(module mq3_two_show_ambiguous
(import mq3_two_show_ambiguous_a)
(import mq3_two_show_ambiguous_b)
(fn main
(doc "mq.3.6 fixture (a): bare `show 42` in a workspace where two Show classes (in modA and modB) each ship Show Int. Without an explicit qualifier the dispatch is genuinely ambiguous; the typechecker must fire `ambiguous-method-resolution` naming both candidate classes.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_str (app show 42)))))
+10
View File
@@ -0,0 +1,10 @@
(module mq3_two_show_ambiguous_a
(class Show
(param a)
(method show
(type (fn-type (params (borrow a)) (ret (con Str))))))
(instance
(class Show)
(type (con Int))
(method show
(body (lam (params (typed x (con Int))) (ret (con Str)) (body (app int_to_str x)))))))
+10
View File
@@ -0,0 +1,10 @@
(module mq3_two_show_ambiguous_b
(class Show
(param a)
(method show
(type (fn-type (params (borrow a)) (ret (con Str))))))
(instance
(class Show)
(type (con Int))
(method show
(body (lam (params (typed x (con Int))) (ret (con Str)) (body (app int_to_str x)))))))
+8
View File
@@ -0,0 +1,8 @@
(module mq3_two_show_qualified
(import mq3_two_show_ambiguous_a)
(import mq3_two_show_ambiguous_b)
(fn main
(doc "mq.3.6 fixture (b): explicit qualifier `mq3_two_show_ambiguous_a.Show.show 42` disambiguates the same workspace as fixture (a). Resolves cleanly to modA's class; typecheck passes.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_str (app mq3_two_show_ambiguous_a.Show.show 42)))))
+5
View File
@@ -0,0 +1,5 @@
(module ne_at_int_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (if (app ne 3 5) 1 0)))))
+9
View File
@@ -0,0 +1,9 @@
(module ordering_match
(fn main
(doc "Iter 23.1 fixture: pattern-match on prelude Ordering ctor without explicit prelude import.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (match (term-ctor prelude.Ordering LT)
(case (pat-ctor LT) 1)
(case (pat-ctor EQ) 2)
(case (pat-ctor GT) 3))))))
+13
View File
@@ -0,0 +1,13 @@
(module poly_apply
(fn apply
(type (forall (vars a b) (fn-type (params (fn-type (params a) (ret b)) a) (ret b))))
(params f x)
(body (app f x)))
(fn succ
(type (fn-type (params (con Int)) (ret (con Int))))
(params n)
(body (app + n 1)))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app apply succ 41)))))
+9
View File
@@ -0,0 +1,9 @@
(module poly_id
(fn id
(type (forall (vars a) (fn-type (params a) (ret a))))
(params x)
(body x))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (app id 42)) (do io/print_bool (app id true))))))
+10
View File
@@ -0,0 +1,10 @@
(module rc_box_drop
(data Box
(doc "Single-cell ADT around an Int. Iter 18c.3 RC fixture: shallow free is sufficient because Box has no boxed children.")
(ctor MkBox (con Int)))
(fn main
(doc "Bind a heap-allocated MkBox to `b`, read its Int via match, print it. Under --alloc=rc, codegen emits `ailang_rc_dec(b)` at the let scope close: `b` is unique, has zero consume uses (only the match scrutinee, a borrow), and the body's tail value is the printed Unit, not `b` itself. The Box has no boxed children so shallow `free()` is correct.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let b (term-ctor Box MkBox 42) (match b
(case (pat-ctor MkBox x) (do io/print_int x)))))))
+17
View File
@@ -0,0 +1,17 @@
(module rc_list_drop
(data IntList
(doc "Recursive Int list. Iter 18c.4 RC fixture: codegen emits `drop_rc_list_drop_IntList` whose `Cons` arm recursively calls itself on the tail field.")
(ctor Nil)
(ctor Cons (con Int) (con IntList)))
(fn sum_list
(doc "Recursive fold over IntList.")
(type (fn-type (params (con IntList)) (ret (con Int))))
(params xs)
(body (match xs
(case (pat-ctor Nil) 0)
(case (pat-ctor Cons h t) (app + h (app sum_list t))))))
(fn main
(doc "Build a 5-element IntList [1,2,3,4,5] and print its sum (15). Under --alloc=rc the recursive drop_rc_list_drop_IntList fn cascades through the tail at process exit when sum_list returns ownership-implicit (the consume_count of `xs` is 1 so no dec at the outer let; the test's correctness invariant is the byte-identical stdout — leak quantification is 18f's bench).")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let xs (term-ctor IntList Cons 1 (term-ctor IntList Cons 2 (term-ctor IntList Cons 3 (term-ctor IntList Cons 4 (term-ctor IntList Cons 5 (term-ctor IntList Nil)))))) (do io/print_int (app sum_list xs))))))
+12
View File
@@ -0,0 +1,12 @@
(module rc_list_drop_borrow
(data IntList
(doc "Recursive Int list. Iter 18c.4 RC fixture: codegen emits a recursive drop fn; this fixture keeps the binder consume_count at 0 so the drop call actually fires at scope close, exercising the recursive cascade at runtime over a 5-element list.")
(ctor Nil)
(ctor Cons (con Int) (con IntList)))
(fn main
(doc "Build a 5-element IntList and print only its head via match. xs has consume_count == 0 (only the match scrutinee, a borrow), so under --alloc=rc the let scope close emits `drop_rc_list_drop_borrow_IntList(xs)` which recursively dec-cascades over the whole 5-cell chain.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let xs (term-ctor IntList Cons 11 (term-ctor IntList Cons 22 (term-ctor IntList Cons 33 (term-ctor IntList Cons 44 (term-ctor IntList Cons 55 (term-ctor IntList Nil)))))) (match xs
(case (pat-ctor Nil) (do io/print_int 0))
(case (pat-ctor Cons h t) (do io/print_int h)))))))
+5
View File
@@ -0,0 +1,5 @@
(module show_mono_pin_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s1 (app show 42) (let s2 (app show true) (let s3 (app show "x") (let s4 (app show 1.5) (do io/print_str s1))))))))
+5
View File
@@ -0,0 +1,5 @@
(module show_no_instance
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let f (lam (params (typed x (con Int))) (ret (con Int)) (body x)) (app print f)))))
+5
View File
@@ -0,0 +1,5 @@
(module show_print_smoke
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (seq (seq (app print 42) (app print true)) (app print "hello")) (app print 3.14)))))
+13
View File
@@ -0,0 +1,13 @@
(module show_user_adt
(data IntBox
(ctor MkIntBox (con Int)))
(instance
(class prelude.Show)
(type (con IntBox))
(method show
(body (lam (params (typed x (con IntBox))) (ret (con Str)) (body (match x
(case (pat-ctor MkIntBox n) (app int_to_str n))))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (app print (term-ctor IntBox MkIntBox 7)))))
+30
View File
@@ -0,0 +1,30 @@
(module sort
(data IntList
(doc "Singly-linked Int list, boxed.")
(ctor Nil)
(ctor Cons (con Int) (con IntList)))
(fn insert
(doc "Insert y into a sorted list xs, preserving order.")
(type (fn-type (params (con Int) (con IntList)) (ret (con IntList))))
(params y xs)
(body (match xs
(case (pat-ctor Nil) (term-ctor IntList Cons y (term-ctor IntList Nil)))
(case (pat-ctor Cons h t) (if (app <= y h) (term-ctor IntList Cons y (term-ctor IntList Cons h t)) (term-ctor IntList Cons h (app insert y t)))))))
(fn sort
(doc "Insertion sort: build the result by inserting each head into the sorted tail.")
(type (fn-type (params (con IntList)) (ret (con IntList))))
(params xs)
(body (match xs
(case (pat-ctor Nil) (term-ctor IntList Nil))
(case (pat-ctor Cons h t) (app insert h (app sort t))))))
(fn print_list
(type (fn-type (params (con IntList)) (ret (con Unit)) (effects IO)))
(params xs)
(body (match xs
(case (pat-ctor Nil) (lit-unit))
(case (pat-ctor Cons h t) (seq (do io/print_int h) (tail-app print_list t))))))
(fn main
(doc "Sort and print [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let xs (term-ctor IntList Cons 3 (term-ctor IntList Cons 1 (term-ctor IntList Cons 4 (term-ctor IntList Cons 1 (term-ctor IntList Cons 5 (term-ctor IntList Cons 9 (term-ctor IntList Cons 2 (term-ctor IntList Cons 6 (term-ctor IntList Cons 5 (term-ctor IntList Cons 3 (term-ctor IntList Cons 5 (term-ctor IntList Nil)))))))))))) (app print_list (app sort xs))))))
+6
View File
@@ -0,0 +1,6 @@
(module str_clone_cross_realisation
(fn main
(doc "Iter 24.1: cross-realisation invariant for str_clone. Clones a heap-Str (produced by int_to_str 42) AND a static-Str (literal `abc`); both clones produce fresh heap-Str slabs that print their input bytes. Pins the uniform-consumer-ABI claim — str_clone only reads the len-field at offset 0 plus the bytes plus the NUL; it never consults the (absent for static-Str) rc_header. RC stats under --alloc=rc: allocs == 3 (int_to_str output + two str_clone outputs), frees == 3, live == 0.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let src_heap (app int_to_str 42) (let c1 (app str_clone src_heap) (let c2 (app str_clone "abc") (let _a (do io/print_str c1) (do io/print_str c2))))))))
+6
View File
@@ -0,0 +1,6 @@
(module str_clone_drop_rc
(fn main
(doc "Iter 24.1: pin that `str_clone` participates in RC discipline AND emits correct bytes. Input is a static-Str literal; the clone produces a fresh heap-Str slab whose payload is byte-equal to the input. RC stats under --alloc=rc with AILANG_RC_STATS=1: allocs == 1 (the clone), frees == 1 (let-binder drop at scope close), live == 0.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let s (app str_clone "hello") (do io/print_str s)))))
+10
View File
@@ -0,0 +1,10 @@
(module str_field_in_adt_heap
(data Boxed
(doc "Iter hs.4 fixture: single-cell ADT around a Str field. Used to pin the drop discipline for ADTs that carry a heap-Str payload — both the ADT cell and the heap-Str inside it must round-trip through the RC walk.")
(ctor Box (con Str)))
(fn main
(doc "Iter hs.4: pin that `field_drop_call` for `Str` correctly dispatches to `ailang_rc_dec` when the Str payload is heap-Str. Construct `Box(int_to_str(42))`, bind, pattern-match to read the Str, print it. Under --alloc=rc with AILANG_RC_STATS=1: allocs >= 2 (ADT cell + heap-Str slab), allocs == frees, live == 0. drop.rs's Str-arm comment names the codegen-level elision that protects static-Str from this same path; here the Str is heap-allocated so rc_dec is the right (and only) consumer.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (let b (term-ctor Boxed Box (app int_to_str 42)) (match b
(case (pat-ctor Box s) (do io/print_str s)))))))
+10
View File
@@ -0,0 +1,10 @@
(module sum
(fn sum
(doc "rekursive Summe 0..=n")
(type (fn-type (params (con Int)) (ret (con Int))))
(params n)
(body (if (app == n 0) 0 (app + n (app sum (app - n 1))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app sum 10)))))
+8
View File
@@ -0,0 +1,8 @@
(module test_22b1_dup_a
(import test_22b1_dup_b)
(import test_22b1_dup_classmod)
(instance
(class test_22b1_dup_classmod.TShow)
(type (con test_22b1_dup_b.MyInt))
(method tshow
(body "from-a"))))
+9
View File
@@ -0,0 +1,9 @@
(module test_22b1_dup_b
(import test_22b1_dup_classmod)
(data MyInt
(ctor MkMyInt (con Int)))
(instance
(class test_22b1_dup_classmod.TShow)
(type (con MyInt))
(method tshow
(body "from-b"))))
+5
View File
@@ -0,0 +1,5 @@
(module test_22b1_dup_classmod
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str)))))))
+4
View File
@@ -0,0 +1,4 @@
(module test_22b1_dup_entry
(import test_22b1_dup_a)
(import test_22b1_dup_b)
(import test_22b1_dup_classmod))
+15
View File
@@ -0,0 +1,15 @@
(module test_22b1_dup_same_module
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body "first")))
(instance
(class TShow)
(type (con Int))
(method tshow
(body "second"))))
+12
View File
@@ -0,0 +1,12 @@
(module test_22b1_missing_method
(class TEq
(param a)
(method teq
(type (fn-type (params a a) (ret (con Bool)))))
(method tne
(type (fn-type (params a a) (ret (con Bool))))))
(instance
(class TEq)
(type (con Int))
(method tne
(body false))))
+10
View File
@@ -0,0 +1,10 @@
(module test_22b1_orphan_class
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body "<int>"))))
+7
View File
@@ -0,0 +1,7 @@
(module test_22b1_orphan_third
(import test_22b1_orphan_third_classmod)
(instance
(class test_22b1_orphan_third_classmod.TShow)
(type (con Int))
(method tshow
(body "<int>"))))
@@ -0,0 +1,5 @@
(module test_22b1_orphan_third_classmod
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str)))))))
@@ -0,0 +1,10 @@
(module test_22b2_class_method_lookup
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body "n"))))
@@ -0,0 +1,9 @@
(module test_22b2_constraint_declared
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(fn describe
(type (forall (vars a) (constraints (constraint TShow a)) (fn-type (params a) (ret (con Str)))))
(params x)
(body (app tshow x))))
@@ -0,0 +1,14 @@
(module test_22b2_constraint_declared_via_superclass
(class TEq
(param a)
(method teq
(type (fn-type (params a a) (ret (con Bool))))))
(class TOrd
(param a)
(superclass (class TEq) (type a))
(method tlt
(type (fn-type (params a a) (ret (con Bool))))))
(fn uses_eq_via_ord
(type (forall (vars a) (constraints (constraint TOrd a)) (fn-type (params a a) (ret (con Bool)))))
(params x y)
(body (app teq x y))))
+14
View File
@@ -0,0 +1,14 @@
(module test_22b2_instance_present
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body (lam (params (typed x a)) (ret (con Str)) (body "n")))))
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (app tshow 42))))
@@ -0,0 +1,9 @@
(module test_22b2_method_name_collision_class_class
(class A
(param a)
(method foo
(type (fn-type (params a) (ret (con Unit))))))
(class B
(param b)
(method foo
(type (fn-type (params b) (ret (con Unit)))))))
@@ -0,0 +1,9 @@
(module test_22b2_method_name_collision_class_fn
(class Greet
(param a)
(method greet
(type (fn-type (params a) (ret (con Str))))))
(fn greet
(type (fn-type (params (con Int)) (ret (con Str))))
(params x)
(body "hi")))
@@ -0,0 +1,9 @@
(module test_22b2_missing_constraint
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(fn describe
(type (forall (vars a) (fn-type (params a) (ret (con Str)))))
(params x)
(body (app tshow x))))
@@ -0,0 +1,14 @@
(module test_22b2_missing_constraint_subclass
(class TEq
(param a)
(method teq
(type (fn-type (params a a) (ret (con Bool))))))
(class TOrd
(param a)
(superclass (class TEq) (type a))
(method tlt
(type (fn-type (params a a) (ret (con Bool))))))
(fn needs_ord_but_only_has_eq
(type (forall (vars a) (constraints (constraint TEq a)) (fn-type (params a a) (ret (con Bool)))))
(params x y)
(body (app tlt x y))))
@@ -0,0 +1,15 @@
(module test_22b2_missing_superclass_instance
(class TEq
(param a)
(method teq
(type (fn-type (params a a) (ret (con Bool))))))
(class TOrd
(param a)
(superclass (class TEq) (type a))
(method tlt
(type (fn-type (params a a) (ret (con Bool))))))
(instance
(class TOrd)
(type (con Int))
(method tlt
(body true))))
+9
View File
@@ -0,0 +1,9 @@
(module test_22b2_no_instance
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (app tshow 42))))
@@ -0,0 +1,12 @@
(module test_22b2_overriding_nonexistent
(class TEq
(param a)
(method teq
(type (fn-type (params a a) (ret (con Bool))))))
(instance
(class TEq)
(type (con Int))
(method teq
(body true))
(method ne
(body false))))
@@ -0,0 +1,13 @@
(module test_22b2_two_fns_missing_constraint
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(fn describe_first
(type (forall (vars a) (fn-type (params a) (ret (con Str)))))
(params x)
(body (app tshow x)))
(fn describe_second
(type (forall (vars b) (fn-type (params b) (ret (con Str)))))
(params y)
(body (app tshow y))))
+10
View File
@@ -0,0 +1,10 @@
(module test_22b2_xmod_classmod
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body (lam (params (typed x a)) (ret (con Str)) (body "n"))))))
@@ -0,0 +1,5 @@
(module test_22b2_xmod_classmod_noinst
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str)))))))
@@ -0,0 +1,6 @@
(module test_22b2_xmod_instance_present
(import test_22b2_xmod_classmod)
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (app tshow 42))))
@@ -0,0 +1,6 @@
(module test_22b2_xmod_missing_constraint
(import test_22b2_xmod_classmod_noinst)
(fn describe
(type (forall (vars a) (fn-type (params a) (ret (con Str)))))
(params x)
(body (app tshow x))))
+6
View File
@@ -0,0 +1,6 @@
(module test_22b2_xmod_no_instance
(import test_22b2_xmod_classmod_noinst)
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (app tshow 42))))
+22
View File
@@ -0,0 +1,22 @@
(module test_22b3_chained_calls
(class B
(param a)
(method b_method
(type (fn-type (params a) (ret (con Int))))))
(class A
(param a)
(method a_method
(type (fn-type (params a) (ret (con Int))))
(default (lam (params (typed x a)) (ret (con Int)) (body (app b_method x))))))
(instance
(class B)
(type (con Int))
(method b_method
(body (lam (params (typed y a)) (ret (con Int)) (body y)))))
(instance
(class A)
(type (con Int)))
(fn main
(type (fn-type (params) (ret (con Int))))
(params)
(body (app a_method 5))))
@@ -0,0 +1,19 @@
(module test_22b3_coherence_two_instances
(class R
(param a)
(method r
(type (fn-type (params a) (ret (con Int))))))
(instance
(class R)
(type (con Int))
(method r
(body (lam (params (typed x a)) (ret (con Int)) (body 11)))))
(instance
(class R)
(type (con Bool))
(method r
(body (lam (params (typed b a)) (ret (con Int)) (body 22)))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (seq (do io/print_int (app r 0)) (do io/print_int (app r true))))))
+13
View File
@@ -0,0 +1,13 @@
(module test_22b3_default_e2e
(class D
(param a)
(method dval
(type (fn-type (params a) (ret (con Int))))
(default (lam (params (typed x a)) (ret (con Int)) (body 99)))))
(instance
(class D)
(type (con Int)))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app dval 0)))))
+14
View File
@@ -0,0 +1,14 @@
(module test_22b3_dup_call_sites
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body (lam (params (typed x a)) (ret (con Str)) (body "n")))))
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (let _a (app tshow 5) (app tshow 7)))))
+14
View File
@@ -0,0 +1,14 @@
(module test_22b3_mono_synthetic
(class Foo
(param a)
(method foo
(type (fn-type (params a) (ret (con Int))))))
(instance
(class Foo)
(type (con Int))
(method foo
(body (lam (params (typed i a)) (ret (con Int)) (body i)))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app foo 5)))))
+14
View File
@@ -0,0 +1,14 @@
(module test_22b3_no_call_sites
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body (lam (params (typed x a)) (ret (con Str)) (body "n")))))
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body "no-call")))
@@ -0,0 +1,23 @@
(module test_22b3_shadow_class_method
(class TShow
(param a)
(method tshow
(type (fn-type (params a) (ret (con Str))))))
(class Foo
(param a)
(method foo
(type (fn-type (params a) (ret (con Str))))))
(instance
(class TShow)
(type (con Int))
(method tshow
(body (lam (params (typed x a)) (ret (con Str)) (body "s")))))
(instance
(class Foo)
(type (con Int))
(method foo
(body (lam (params (typed x a)) (ret (con Str)) (body "f")))))
(fn main
(type (fn-type (params) (ret (con Str))))
(params)
(body (let _t (app tshow 5) (let tshow "shadow" (let _u tshow (app foo 7)))))))
+10
View File
@@ -0,0 +1,10 @@
(module test_22b3_xmod_e2e_classmod
(class XR
(param a)
(method xr
(type (fn-type (params a) (ret (con Int))))))
(instance
(class XR)
(type (con Int))
(method xr
(body (lam (params (typed x a)) (ret (con Int)) (body 7))))))
+6
View File
@@ -0,0 +1,6 @@
(module test_22b3_xmod_e2e_main
(import test_22b3_xmod_e2e_classmod)
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app xr 0)))))
+17
View File
@@ -0,0 +1,17 @@
(module test_22c_user_class_e2e
(data IntBox
(ctor MkIntBox (con Int)))
(class Foo
(param a)
(method foo
(type (fn-type (params (borrow a)) (ret (con Int))))))
(instance
(class Foo)
(type (con IntBox))
(method foo
(body (lam (params (typed b a)) (ret (con Int)) (body (match b
(case (pat-ctor MkIntBox v) v)))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app foo (term-ctor IntBox MkIntBox 42))))))
+5
View File
@@ -0,0 +1,5 @@
(module test_mono_ctor_listmod
(data List (vars a)
(doc "Minimal polymorphic list for the mono-pass cross-module ctor-pattern bug fixture.")
(ctor Nil)
(ctor Cons a (con List a))))
+22
View File
@@ -0,0 +1,22 @@
(module test_mono_ctor_main
(import test_mono_ctor_listmod)
(class Trivial
(param a)
(method trivial
(type (fn-type (params a) (ret (con Int))))))
(instance
(class Trivial)
(type (con Int))
(method trivial
(body (lam (params (typed x (con Int))) (ret (con Int)) (body x)))))
(fn head_or_zero
(doc "Pattern-matches Cons from an imported module's List<Int>. Bug repro: with a class+instance present in the workspace, the mono pass walks this body and synth's local-flat ctor_index resolves Cons to bare \"List\", which mismatches the qualified scrutinee type \"test_mono_ctor_listmod.List<Int>\".")
(type (fn-type (params (con test_mono_ctor_listmod.List (con Int))) (ret (con Int))))
(params xs)
(body (match xs
(case (pat-ctor Cons h _) h)
(case (pat-ctor Nil) 0))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app head_or_zero (term-ctor test_mono_ctor_listmod.List Cons 7 (term-ctor test_mono_ctor_listmod.List Nil)))))))
+14
View File
@@ -0,0 +1,14 @@
(module test_mono_imports_classmod
(class Foo
(param a)
(method foo
(type (fn-type (params a) (ret (con Int))))))
(instance
(class Foo)
(type (con Int))
(method foo
(body (lam (params (typed x a)) (ret (con Int)) (body x)))))
(fn helper
(type (fn-type (params (con Int)) (ret (con Int))))
(params n)
(body (app + n 100))))
+6
View File
@@ -0,0 +1,6 @@
(module test_mono_imports_main
(import test_mono_imports_classmod)
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app test_mono_imports_classmod.helper 42)))))
+18
View File
@@ -0,0 +1,18 @@
(module test_mono_recursive_fn_bug
(class Foo
(param a)
(method foo
(type (fn-type (params a) (ret (con Int))))))
(instance
(class Foo)
(type (con Int))
(method foo
(body (lam (params (typed x a)) (ret (con Int)) (body x)))))
(fn loop
(type (fn-type (params (con Int) (con Int)) (ret (con Int))))
(params acc i)
(body (if (app == i 0) acc (tail-app loop (app + acc i) (app - i 1)))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app loop 0 5)))))
+7
View File
@@ -0,0 +1,7 @@
(module ws_broken
(import ws_lib)
(fn main
(doc "Iter 5b negative fixture: ruft ws_lib.bogus auf — Modul existiert, Def nicht. Triggert `unknown-import`.")
(type (fn-type (params) (ret (con Int))))
(params)
(body (app ws_lib.bogus 1 2))))
+6
View File
@@ -0,0 +1,6 @@
(module ws_lib
(fn add
(doc "Iter 5a fixture: einfache Add-Funktion, die ws_main importiert.")
(type (fn-type (params (con Int) (con Int)) (ret (con Int))))
(params a b)
(body (app + a b))))
+7
View File
@@ -0,0 +1,7 @@
(module ws_main
(import ws_lib)
(fn main
(doc "Iter 5b fixture: ruft ws_lib.add auf, druckt das Ergebnis. So ist Cross-Module-Typcheck am Beispiel beobachtbar.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body (do io/print_int (app ws_lib.add 2 3)))))
+6
View File
@@ -0,0 +1,6 @@
(module ws_unknown_module
(fn main
(doc "Iter 5b negative fixture: kein Import, aber qualifizierter Verweis `nope.x`. Triggert `unknown-module`.")
(type (fn-type (params) (ret (con Int))))
(params)
(body nope.x)))