Skip to content

Commit 5407b5e

Browse files
authored
Initial term checker and constraint solver (#75)
2 parents 7b992c6 + 369fbf0 commit 5407b5e

File tree

354 files changed

+12358
-2917
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

354 files changed

+12358
-2917
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
name: type-checker-tests
3+
description: Add integration tests for type checker inference and checking functions
4+
---
5+
6+
# Type Checker Integration Tests
7+
8+
Use this skill when adding new type checker functions or expanding behavior.
9+
10+
**Language:** Test fixtures use PureScript syntax, not Haskell.
11+
12+
## Quick Reference
13+
14+
| Action | Command |
15+
|--------|---------|
16+
| Find next test number | `ls tests-integration/fixtures/checking/ \| tail -5` |
17+
| Run specific test | `just tc NNN` |
18+
| Run all checking tests | `just tc` |
19+
| Accept all pending snapshots | `cargo insta accept` |
20+
21+
Use `just tc --help` for all options.
22+
23+
## Creating a Test
24+
25+
### 1. Create fixture directory
26+
27+
```bash
28+
mkdir tests-integration/fixtures/checking/{NNN_descriptive_name}
29+
```
30+
31+
Tests are auto-discovered by `build.rs` - no manual registration needed.
32+
33+
### 2. Write Main.purs
34+
35+
**Standard pattern** - pair typed (checking) and untyped (inference) variants:
36+
37+
```purescript
38+
module Main where
39+
40+
-- Checking mode: explicit signature constrains type checker
41+
test :: Array Int -> Int
42+
test [x] = x
43+
44+
-- Inference mode: type checker infers unconstrained
45+
test' [x] = x
46+
```
47+
48+
**Guidelines:**
49+
- Test ONE specific behavior per fixture
50+
- Name tests descriptively: `test`, `test'`, `test2`, `test2'`, etc.
51+
- Include edge cases relevant to the behavior being tested
52+
53+
### 3. Generate and review snapshot
54+
55+
```bash
56+
just tc NNN
57+
```
58+
59+
This outputs:
60+
- `CREATED path` (green) with numbered lines showing full content
61+
- `UPDATED path` (yellow) with chunked diff (2 lines context, line numbers)
62+
63+
## Multi-File Tests
64+
65+
For testing imports, re-exports, or cross-module behavior, add multiple `.purs` files
66+
to the same fixture directory. The type checker loads all `.purs` files in the folder.
67+
68+
**Example structure:**
69+
```
70+
tests-integration/fixtures/checking/NNN_import_test/
71+
├── Main.purs # The test file (snapshot generated for Main)
72+
├── Lib.purs # Supporting module
73+
└── Main.snap # Generated snapshot
74+
```
75+
76+
**Lib.purs:**
77+
```purescript
78+
module Lib where
79+
80+
life :: Int
81+
life = 42
82+
83+
data Maybe a = Just a | Nothing
84+
```
85+
86+
**Main.purs:**
87+
```purescript
88+
module Main where
89+
90+
import Lib (life, Maybe(..))
91+
92+
test :: Maybe Int
93+
test = Just life
94+
```
95+
96+
**Key points:**
97+
- Module name must match filename (`Lib.purs` -> `module Lib where`)
98+
- Only `Main.purs` generates a snapshot (the test runs against `Main`)
99+
- Use standard PureScript import syntax
100+
101+
## Reviewing Snapshots
102+
103+
Snapshots have this structure:
104+
105+
```
106+
Terms
107+
functionName :: InferredOrCheckedType
108+
...
109+
110+
Types
111+
TypeName :: Kind
112+
...
113+
114+
Errors
115+
ErrorKind { details } at [location]
116+
```
117+
118+
### Acceptance Criteria
119+
120+
**Before accepting, verify:**
121+
122+
1. **Types are correct** - Check that inferred types match expectations
123+
- `test :: Array Int -> Int` - explicit signature preserved
124+
- `test' :: forall t. Array t -> t` - polymorphism inferred correctly
125+
126+
2. **No unexpected `???`** - This indicates inference failure
127+
- `test :: ???` - STOP: the term failed to type check
128+
- `CannotUnify { ??? -> ???, Int }` - OK in error tests, shows unresolved unification variables
129+
130+
3. **Errors appear where expected** - For tests validating error behavior
131+
- Confirm error kind matches expectations (e.g., `NoInstanceFound`, `CannotUnify`)
132+
- Verify error location points to the correct declaration
133+
134+
4. **Polymorphism is appropriate**
135+
- Check type variable names (`t6`, `a`, etc.) are scoped correctly
136+
- Verify constraints propagate as expected
137+
138+
### Common Issues
139+
140+
| Symptom | Likely Cause |
141+
|---------|--------------|
142+
| `test :: ???` | Test code has syntax error or uses undefined names |
143+
| Unexpected monomorphism | Missing polymorphic context or over-constrained signature |
144+
| Wrong error location | Check binder/expression placement in source |
145+
| Missing types in snapshot | Module header or imports incorrect |
146+
147+
## Accept and Verify
148+
149+
```bash
150+
# Accept only after thorough review
151+
cargo insta accept
152+
153+
# Verify full suite passes
154+
just tc
155+
```
156+
157+
## Debugging
158+
159+
When investigating a potential compiler bug:
160+
161+
```bash
162+
# Focus on single test to reduce noise
163+
just tc NNN
164+
```
165+
166+
Once the issue is resolved, run the full test suite to check for regressions.

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "monthly"

.github/workflows/checks.yml

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,15 @@ jobs:
2929
run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
3030

3131
- name: Cache build artifacts
32-
uses: Swatinem/rust-cache@v2.8.0
32+
uses: Swatinem/rust-cache@v2.8.2
3333
with:
3434
cache-bin: "false"
35-
prefix-key: "v5-maho-${{ matrix.os }}-${{ matrix.toolchain }}"
35+
prefix-key: "v6-maho-${{ matrix.os }}-${{ matrix.toolchain }}"
3636

37-
- name: Install cargo-binstall
38-
uses: cargo-bins/cargo-binstall@v1.15.3
39-
40-
- name: Install cargo-nextest
41-
run: cargo binstall cargo-nextest just
42-
env:
43-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
- name: Install tools
38+
uses: taiki-e/install-action@v2
39+
with:
40+
tool: cargo-nextest,just
4441

4542
- name: Build and Test
4643
run: |
@@ -64,18 +61,15 @@ jobs:
6461
run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
6562

6663
- name: Cache build artifacts
67-
uses: Swatinem/rust-cache@v2.8.0
64+
uses: Swatinem/rust-cache@v2.8.2
6865
with:
6966
cache-bin: "false"
70-
prefix-key: "v5-maho-${{ matrix.toolchain }}"
67+
prefix-key: "v6-maho-${{ matrix.toolchain }}"
7168

72-
- name: Install cargo-binstall
73-
uses: cargo-bins/cargo-binstall@v1.15.3
74-
75-
- name: Install cargo-nextest
76-
run: cargo binstall cargo-nextest cargo-llvm-cov just
77-
env:
78-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69+
- name: Install tools
70+
uses: taiki-e/install-action@v2
71+
with:
72+
tool: cargo-nextest,cargo-llvm-cov,just
7973

8074
- name: Build and Test
8175
run: |

AGENTS.md

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -42,61 +42,35 @@ Additional concepts that you should be mindful of, the compiler:
4242
- uses techniques like interning and arena allocation to enable better caching patterns
4343
- for instance, whitespace does not immediately invalidate type checking results
4444

45-
## Niche Guides
45+
## Skills
4646

47-
Load these guides from `agents/guides/` when working on related tasks:
48-
- `build-system.md` - working with the build system
49-
- `integration-tests.md` - working with fixtures and snapshots
47+
Agent skills are specialized instruction sets for common tasks. They're stored in `.claude/skills/`.
5048

51-
## Communication Guidelines
49+
- **type-checker-tests**: Adding integration tests for type checker inference and checking
5250

53-
When working on this project, prefer succinct and direct responses. Keep output tokens
54-
minimal to reduce costs while using the default thinking budget to maintain reasoning.
51+
## Commands
5552

56-
**Key principles:**
57-
- Provide brief, direct answers to queries
58-
- Only elaborate when explicitly asked
59-
- Keep output focused on what's necessary
60-
- Avoid verbose explanations unless requested
61-
- Do not write or edit code until permitted to do so
53+
This is your bread and butter to verify that code compiles, including test code.
54+
If updating the test code can be deferred, you may skip adding the `--tests flag`
55+
to speed up the task at hand.
6256

63-
## Development Commands
64-
65-
`cargo check` to verify what you've written is correct
66-
67-
```bash
68-
# Check all crates
69-
cargo check
70-
71-
# Check a crate
72-
cargo check -p indexing
7357
```
74-
75-
`cargo nextest` to run tests blazingly fast
76-
77-
```bash
78-
# Run unit tests for a specific crate
79-
cargo nextest run -p indexing
80-
81-
# Run integration tests
82-
just integration
83-
84-
# Run integration tests with filters
85-
just integration --test resolving 001
58+
cargo check -p <crate-name> --tests
8659
```
8760

88-
`cargo clippy` and `cargo fmt` for code quality
89-
90-
```bash
91-
# Get diagnostics from clippy
92-
cargo clippy --workspace
61+
When working on the type checker `./compiler-core/checking/` you must run
62+
the full type checker snapshot test suite using the following command to
63+
verify if there's any change in behaviour. Use the `type-checker-tests`
64+
skill when asked to develop more type checker tests.
9365

94-
# Format with stable and nightly
95-
cargo fmt && just format-imports
66+
```
67+
just tc
9668
```
9769

98-
### Testing Loop
70+
You can also specify a test fixture number to reduce noise. Once you've
71+
identified and fixed the bug, you must run the full test suite again to
72+
verify that the fix generalises.
9973

100-
This project uses `cargo-insta` for snapshot tests. Fresh snapshots are prefixed with `.snap.new`,
101-
make sure to review these if a test run produces them. Use `cargo insta accept` once you're satisfied
102-
with the output.
74+
```
75+
just tc 101
76+
```

0 commit comments

Comments
 (0)