Files
AILang/crates/ailang-core
Brummel 078262271a Iter 13a: parameterised ADT schema + checker
Adds type parameters to ADTs. `TypeDef` gets a `vars: Vec<String>` and
`Type::Con` gets an `args: Vec<Type>`, both `skip_serializing_if =
"Vec::is_empty"` so canonical-JSON hashes of every pre-13a definition
stay bit-identical (regression test in `hash::tests`).

Checker:
- `check_type_def` installs `td.vars` as rigid vars while validating
  ctor field types — `Cons(a, List a)` now resolves both occurrences
  of `a` and the recursive `List a` use.
- `check_type_well_formed` accepts `Type::Con { name, args }` only
  when the type is in scope and `args.len()` matches its declared
  arity; primitives stay zero-arg.
- `Term::Ctor` synth instantiates `td.vars` with fresh metavars, so
  `MkBox(42)` synthesises to `Box<$m0>` and unifies field types
  through the surrounding context.
- `type_check_pattern` substitutes the scrutinee's concrete type-args
  through ctor field types, so a `MkBox(x)` arm against a `Box<Int>`
  scrutinee binds `x : Int`.
- `check_fn` validates declared param/return types via
  `check_type_well_formed` so arity mismatches on parameterised
  ADTs surface before the body is checked.

`unify`, `occurs`, `Subst::apply`, `substitute_rigids`, and codegen's
`unify_for_subst` / `apply_subst_to_type` recurse into `args`.

Pretty-print:
- `type_to_string` renders `Box<Int>` for parameterised cons.
- `def_block`/`manifest` carry the `[a b ...]` vars list.

Three new check unit tests cover ctor instantiation at a concrete
arg, the polymorphic-`unbox` round trip at two distinct
instantiations, and arity mismatch on `Box<Int, Bool>`. All 62 tests
green; clippy clean (two pre-existing warnings untouched). Hashes
db33f57cb329935e (sum) and b082192bd0c99202 (IntList) verified
unchanged.

Codegen still synthesises `Type::Con` with `args: vec![]` from
`Term::Ctor` — full ADT monomorphisation lands in 13b.
2026-05-07 14:25:58 +02:00
..