Skip to content

feat(types): name types via a symbol, render the nominal name#180

Merged
kollhof merged 1 commit into
mainfrom
type-name-symbol
Jun 21, 2026
Merged

feat(types): name types via a symbol, render the nominal name#180
kollhof merged 1 commit into
mainfrom
type-name-symbol

Conversation

@kollhof

@kollhof kollhof commented Jun 21, 2026

Copy link
Copy Markdown
Member

What

A $Type carries its declared name as a $name symbol (tagged i31) instead of the dead (mod_id, cps_id) pair. The pair was stored and threaded through every type constructor but never resolved host-side; its one intended consumer (printing a type name) was a standing TODO. The renderer now resolves the name symbol in-band via symbol_to_str, so a typed instance reprs and fmts under its nominal name.

Behaviour

  • '${Foo {bar: 1}}' -> Foo {bar: 1} (was {bar: 1})
  • '${[Foo {bar: 1}]}' -> [Foo {bar: 1}]
  • enum cases render named (Some {...})
  • an anonymous type _ (null-name symbol) stays bare-payload

Changes

  • types.wat: replace (mod_id, cps_id) with $name (ref i31) across $Type/$RecType/$TupleType/$Union/$Enum; seed constructors take (ctx, name, cont); type_inherit keeps the derived type's own name (so a subtype reprs under its own name, not its base's); add inst_type_name.
  • repr.wat / str.wat: the $Inst arms prepend the nominal name (inst_repr / inst_fmt).
  • transform.rs: name a type/union/enum declaration after its bind LHS ident; enum case-types after the case name; inline/unbound declarations carry the null name.
  • lower.rs: the type-seed boxes the name symbol via the existing symbol path instead of injecting the dead pair.

Functions are intentionally out of scope - naming a function value is a separate, larger increment (a name field on the universal closure type, threaded at every construction site).

Tests

Full suite green (1366 lib + 42 CLI + 1 JS interop, 0 failures). CPS and WAT type snapshots re-blessed for the new name-symbol seed arg. Clippy clean.

A `$Type` carries its declared name as a `$name` symbol (tagged i31)
instead of the dead `(mod_id, cps_id)` pair, which was stored and
threaded through every constructor but never resolved. The renderer
resolves the symbol to a source name in-band via `symbol_to_str`, so a
typed instance reprs and fmts under its nominal name (`Foo {bar: 1}`).

- types.wat: replace `(mod_id, cps_id)` with `$name (ref i31)` across
  `$Type`/`$RecType`/`$TupleType`/`$Union`/`$Enum`; seed constructors
  take `(ctx, name, cont)`; `type_inherit` keeps the derived type's own
  name; add `inst_type_name`.
- repr.wat / str.wat: `$Inst` arms prepend the nominal name (`inst_repr`
  / `inst_fmt`); an anonymous `type _` (null-name symbol) stays bare.
- transform.rs: name a `type`/`union`/`enum` declaration after its bind
  LHS ident; enum cases after the case name; inline decls stay anonymous.
- lower.rs: the type-seed boxes the name symbol via the symbol path.
@github-actions

Copy link
Copy Markdown

📦 This PR will release v0.88.0 (minor) when merged.

@kollhof kollhof merged commit 52bb670 into main Jun 21, 2026
14 checks passed
@kollhof kollhof deleted the type-name-symbol branch June 21, 2026 09:40
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.

1 participant