Type-check primitives, let/var bindings, and blocks #48

Merged
jacksonopp merged 3 commits from us/2-type-check-primitives-let-var-blocks into main 2026-08-31 20:36:33 +00:00
Owner

Closes #2.

Summary

  • Adds crates/twill-check/src/ty.rs: Ty (unsized primitive types), Scope
    (a stack of frames for let/var binding and lexical shadowing), and the
    checker walk (resolve_type_expr, check_let, check_expr, check_stmt).
  • Resolves TypeExpr::Named for the five primitives (Int/Float/Bool/
    String/Unit); other TypeExpr variants are recognized but not yet
    resolvable, reported as "not supported yet" rather than "unknown".
  • Checks let/var bindings: annotation vs. inferred-value mismatches,
    redeclaration within the same block, and undefined-variable lookups.
  • Types Expr::Block Rust-style: the trailing expression's type (checked
    while its own frame is still active, so it can see the block's own
    bindings), or Ty::Unit if there's no trailing expression.
  • DiagnosticKind on diagnostic.rs's Diagnostic gives every diagnostic
    structured data (Ty/Symbol/TypeExpr payloads) alongside a rendered
    message, instead of ad hoc strings.
  • Wires a new #[salsa::tracked] check(db, file) -> Vec<Diagnostic> query
    into queries.rs, alongside the existing lower query.
  • docs/type-checker-design.md: records the design decisions made along the
    way (scope representation, diagnostic shape, query plumbing, etc.) per its
    own living-doc convention.

Test plan

  • cargo test -p twill-check - 101 tests passing, including new unit
    tests for Scope/resolve_type_expr/check_expr/check_let in ty.rs, and
    end-to-end tests against check() in queries.rs (valid bindings,
    mismatches, redeclaration, undefined variables, block
    scoping/trailing-type behavior).
Closes #2. ## Summary - Adds `crates/twill-check/src/ty.rs`: `Ty` (unsized primitive types), `Scope` (a stack of frames for let/var binding and lexical shadowing), and the checker walk (`resolve_type_expr`, `check_let`, `check_expr`, `check_stmt`). - Resolves `TypeExpr::Named` for the five primitives (`Int`/`Float`/`Bool`/ `String`/`Unit`); other `TypeExpr` variants are recognized but not yet resolvable, reported as "not supported yet" rather than "unknown". - Checks `let`/`var` bindings: annotation vs. inferred-value mismatches, redeclaration within the same block, and undefined-variable lookups. - Types `Expr::Block` Rust-style: the trailing expression's type (checked while its own frame is still active, so it can see the block's own bindings), or `Ty::Unit` if there's no trailing expression. - `DiagnosticKind` on `diagnostic.rs`'s `Diagnostic` gives every diagnostic structured data (`Ty`/`Symbol`/`TypeExpr` payloads) alongside a rendered message, instead of ad hoc strings. - Wires a new `#[salsa::tracked] check(db, file) -> Vec<Diagnostic>` query into `queries.rs`, alongside the existing `lower` query. - `docs/type-checker-design.md`: records the design decisions made along the way (scope representation, diagnostic shape, query plumbing, etc.) per its own living-doc convention. ## Test plan - [x] `cargo test -p twill-check` - 101 tests passing, including new unit tests for Scope/resolve_type_expr/check_expr/check_let in ty.rs, and end-to-end tests against check() in queries.rs (valid bindings, mismatches, redeclaration, undefined variables, block scoping/trailing-type behavior).
jacksonopp deleted branch us/2-type-check-primitives-let-var-blocks 2026-08-31 20:36:33 +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!48
No description provided.