Skip to content

Type-check token definitions#148

Merged
rvcas merged 2 commits into
mainfrom
token-typecheck
Jun 21, 2026
Merged

Type-check token definitions#148
rvcas merged 2 commits into
mainfrom
token-typecheck

Conversation

@rvcas

@rvcas rvcas commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Builds on #138 (parser support). Replaces the parse-only token stubs with full type checking, mirroring the existing utxo machinery. Token codegen is intentionally left as a follow-up.

Builds on #138 — until that merges, this PR also includes its parser commits.

Behavior

A token definition is now checked end to end:

token MyToken {
    storage {
        indexed let mut supply: u32;
        let mut owner: u64;
    }
    mint fn mint() { supply = 1; }   // storage in scope; no explicit return type
    burn fn burn() { supply = 0; }
    impl Token {                      // built-in interface: attach/detach
        fn attach(to: Utxo) {}
        fn detach(source: Utxo) {}
    }
    fn helper() {}
}

Rules enforced: at least one mint fn, exactly one impl Token, mint may not declare a return type, and the impl Token block must match the built-in attach(Utxo) -> () / detach(Utxo) -> () signatures. Additional impl <UserAbi> blocks are allowed.

Changes

  • Type model (types.rs): Type::TokenAny + Type::TokenNamed, parallel to Utxo, threaded through every exhaustive Type match (apply, substitute, occurs/free-vars, env, exhaustiveness, docs, to-wasm handle lowering).
  • Typed AST (typed_ast.rs): TypedTokenDef { name, parts, ty } with TypedTokenPart + TypedTokenGlobal { indexed }.
  • Type checking (infer.rs): register_token (opaque handle), Token annotation → TokenAny, a built-in Token ABI registered at construction so impl Token reuses check_abi_impl, a guard rejecting user-declared abi Token, and infer_token (structural pre-pass, storage scope, mint return-type rule, impl conformance) plus apply_token and type export.
  • Errors: new E0052E0055 with rendered messages and docs.
  • Language server (document.rs): token symbols, hover, and type-annotation collection.
  • Tests: 8 typecheck snapshot tests (valid token + each error path).

Note

Token is now a reserved type name like Utxo. The struct_param.star codegen fixture happened to define struct Token, so it was renamed to struct Item (snapshot regenerated).

Known parallels-to-utxo / deferred

  • check_abi_impl does not enforce parameter arity (pre-existing utxo limitation).
  • No token unify arms (utxo has none either; token-typed values don't flow through unification yet).
  • Token codegen in starstream-to-wasm remains a "not yet supported" stub.

@rvcas rvcas changed the base branch from token-parser-support to main June 15, 2026 17:46
@rvcas rvcas force-pushed the token-typecheck branch from dd6a3ba to fd58bc8 Compare June 15, 2026 18:48

@SpaceManiac SpaceManiac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the right path

rvcas added 2 commits June 20, 2026 21:17
Replace the parse-only stubs for `token` with full type checking, mirroring
the existing `utxo` machinery:

- Add `Type::TokenAny` / `Type::TokenNamed`, parallel to Utxo, and thread them
  through every exhaustive `Type` match.
- Expand `TypedTokenDef` into `{ name, parts, ty }` with `TypedTokenPart` and
  `TypedTokenGlobal { indexed }`.
- `register_token` registers the named type as an opaque handle; the bare
  `Token` annotation resolves to `TokenAny`.
- Register a built-in `Token` ABI (`attach(Utxo) -> ()`, `detach(Utxo) -> ()`)
  so `impl Token` reuses `check_abi_impl`; reject a user-declared `abi Token`.
- `infer_token` validates structure (at least one `mint fn`, exactly one
  `impl Token`) before inferring bodies, checks storage (carrying `indexed`),
  rejects an explicit return type on `mint`, and validates impl conformance.
  Storage is in scope for all token functions.
- Add `apply_token`, export the token name as a type, four new error codes
  (E0052–E0055) with docs, and full language-server symbols/hover.

`Token` is now a reserved type name like `Utxo`; rename the `struct Token` in
the `struct_param.star` codegen fixture to avoid the collision.

Token codegen remains a stub and is left for a follow-up.

Signed-off-by: rvcas <x@rvcas.dev>
Signed-off-by: rvcas <x@rvcas.dev>
@rvcas rvcas force-pushed the token-typecheck branch from b251d9d to c491ff0 Compare June 21, 2026 01:21
@rvcas rvcas merged commit db0473e into main Jun 21, 2026
5 checks passed
@rvcas rvcas deleted the token-typecheck branch June 21, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants