Type-check struct/enum definitions and struct literals #50

Merged
jacksonopp merged 5 commits from us4/type-check-struct-enum into main 2026-09-03 01:45:11 +00:00
Owner

Closes #4.

Summary

  • TyKind::Struct/TyKind::Enum, nominal (carry a name: Symbol), with
    enum variant payloads staying Option<Ty> to distinguish a no-payload
    variant from a resolution failure.
  • check_expr gains a name_hint: Option<Symbol> parameter, populated
    only by check_let, so struct { ... }/enum { ... } declarations can
    be named without needing their own syntax for it (per let X = struct {...}).
    A None hint reports NamelessStruct/NamelessEnum.
  • check_struct_literal checks Expr::StructLiteral against its declared
    struct: name-based (not positional) field matching over the union of
    literal/declared field names, catching unknown fields
    (StructFieldNotDefined), missing required fields (MissingStructType),
    and field type mismatches (StructFieldMismatch) in one pass. A literal
    against an undeclared or non-struct name reports NoStruct.
  • Enum variant construction/matching (Reserved(slot), match) is
    explicitly out of scope — no EnumLiteral HIR node exists; that's
    Expr::Call/Expr::Match checking, later work.
  • check_expr's match arms extracted into their own functions
    (check_ident/check_block/check_fn/check_call/check_struct/
    check_enum/check_struct_literal) to keep it readable as more
    constructs are added.
  • docs/type-checker-design.md gets a new ## Issue #4 section
    documenting these decisions.

Test plan

  • cargo test -p twill-check — 123 tests passing, including 6 new
    tests each for struct/enum declaration checking and struct-literal
    checking (valid case, unknown field, missing field, mismatch,
    not-a-struct, undefined name).
Closes #4. ## Summary - `TyKind::Struct`/`TyKind::Enum`, nominal (carry a `name: Symbol`), with enum variant payloads staying `Option<Ty>` to distinguish a no-payload variant from a resolution failure. - `check_expr` gains a `name_hint: Option<Symbol>` parameter, populated only by `check_let`, so `struct { ... }`/`enum { ... }` declarations can be named without needing their own syntax for it (per `let X = struct {...}`). A `None` hint reports `NamelessStruct`/`NamelessEnum`. - `check_struct_literal` checks `Expr::StructLiteral` against its declared struct: name-based (not positional) field matching over the union of literal/declared field names, catching unknown fields (`StructFieldNotDefined`), missing required fields (`MissingStructType`), and field type mismatches (`StructFieldMismatch`) in one pass. A literal against an undeclared or non-struct name reports `NoStruct`. - Enum variant construction/matching (`Reserved(slot)`, `match`) is explicitly out of scope — no `EnumLiteral` HIR node exists; that's `Expr::Call`/`Expr::Match` checking, later work. - `check_expr`'s match arms extracted into their own functions (`check_ident`/`check_block`/`check_fn`/`check_call`/`check_struct`/ `check_enum`/`check_struct_literal`) to keep it readable as more constructs are added. - `docs/type-checker-design.md` gets a new `## Issue #4` section documenting these decisions. ## Test plan - [x] `cargo test -p twill-check` — 123 tests passing, including 6 new tests each for struct/enum declaration checking and struct-literal checking (valid case, unknown field, missing field, mismatch, not-a-struct, undefined name).
Covers the nominal Struct/Enum Ty shapes, the name_hint mechanism for
naming anonymous struct/enum declarations, the name-based (union-of-keys)
field matching in check_struct_literal, and the new diagnostics.
jacksonopp deleted branch us4/type-check-struct-enum 2026-09-03 01:45:11 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jacksonopp/twill!50
No description provided.