Skip to content

feat: anonymous record literal shorthand {field:val} without typedef#616

Merged
danieljohnmorris merged 4 commits into
mainfrom
feature/anonymous-records
May 22, 2026
Merged

feat: anonymous record literal shorthand {field:val} without typedef#616
danieljohnmorris merged 4 commits into
mainfrom
feature/anonymous-records

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

  • Adds {field:val field2:val2} syntax for ad-hoc structural records without a prior type declaration
  • Type checker synthesises a structural Ty::AnonRecord that unifies with any record of the same field shape
  • Runtime delegates to the existing Value::Record path — zero overhead vs named records

What's included

  • Parser: is_anon_record_literal lookahead ({ ident : ...) unambiguously distinguishes from brace-blocks and destructure patterns; wired into can_start_atom and parse_atom
  • AST: Expr::AnonRecord { fields } with full coverage in alias resolution, desugar, field-collection, free-var collection, and all codegen passes
  • Type checker (verify.rs): Ty::AnonRecord(Vec<(String, Ty)>) — field access, destructure binding, with update, and structural unification (order-independent field matching)
  • Interpreter: eval_expr arm emits Value::Record { type_name: "__anon", fields }
  • VM (RegCompiler): synthesises a shape-stable type name __anon_<sorted_fields> so two literals with the same field set share a registry entry; uses existing OP_RECNEW / OP_RECNEW_EMPTY paths
  • Codegen: fmt.rs and python.rs handle the new variant
  • Example + tests: examples/anon-record.ilo — 9 test cases covering construction, field access, pass-to-fn, return-from-fn, destructure, and with update (all pass)

Test plan

  • cargo build — clean
  • ilo test examples/anon-record.ilo — 9/9 pass
  • cargo test — all tests pass (pre-existing body_is_thin_bootstrap failure is unrelated to this PR and already present on main)

Follow-ups

  • Type-directed coercion: allow passing {name:t} where a named record with a name field is expected (structural subtyping)
  • with adding new fields to anonymous records is currently permitted by the type checker; may want to restrict or document
  • Python codegen emits a plain dict; could add _type sentinel if needed for downstream tooling

Closes ILO-54

🤖 Generated with Claude Code

Adds `{field:val; field2:val2}` syntax for constructing ad-hoc structural
records without a prior `type` declaration. The type checker synthesises
a structural `AnonRecord` type that unifies with other anonymous records
of the same shape.

- Parser: recognises `{ident:...}` in expression position via `is_anon_record_literal` lookahead
- AST: `Expr::AnonRecord { fields }` variant with full desugaring/traversal coverage
- Type checker: `Ty::AnonRecord` structural type with field access, destructure, and `with` update
- Interpreter: evaluates to `Value::Record` with `__anon` type_name
- VM: compiles via `OP_RECNEW` / `OP_RECNEW_EMPTY` with shape-stable synthetic type names
- Codegen: fmt and python backends handle the new variant
- Example: `examples/anon-record.ilo` with 9 passing test cases

Closes ILO-54

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 81.36882% with 49 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/verify.rs 75.86% 14 Missing ⚠️
src/vm/mod.rs 82.14% 10 Missing ⚠️
src/codegen/fmt.rs 0.00% 6 Missing ⚠️
src/codegen/python.rs 40.00% 6 Missing ⚠️
src/parser/mod.rs 82.35% 6 Missing ⚠️
src/graph.rs 0.00% 4 Missing ⚠️
src/interpreter/mod.rs 72.72% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@danieljohnmorris danieljohnmorris merged commit 4669f15 into main May 22, 2026
4 of 5 checks passed
@danieljohnmorris danieljohnmorris deleted the feature/anonymous-records branch May 22, 2026 02:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant