feat: anonymous record literal shorthand {field:val} without typedef#616
Merged
Conversation
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 Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
{field:val field2:val2}syntax for ad-hoc structural records without a priortypedeclarationTy::AnonRecordthat unifies with any record of the same field shapeValue::Recordpath — zero overhead vs named recordsWhat's included
is_anon_record_literallookahead ({ ident : ...) unambiguously distinguishes from brace-blocks and destructure patterns; wired intocan_start_atomandparse_atomExpr::AnonRecord { fields }with full coverage in alias resolution, desugar, field-collection, free-var collection, and all codegen passesverify.rs):Ty::AnonRecord(Vec<(String, Ty)>)— field access, destructure binding,withupdate, and structural unification (order-independent field matching)eval_exprarm emitsValue::Record { type_name: "__anon", fields }RegCompiler): synthesises a shape-stable type name__anon_<sorted_fields>so two literals with the same field set share a registry entry; uses existingOP_RECNEW/OP_RECNEW_EMPTYpathsfmt.rsandpython.rshandle the new variantexamples/anon-record.ilo— 9 test cases covering construction, field access, pass-to-fn, return-from-fn, destructure, andwithupdate (all pass)Test plan
cargo build— cleanilo test examples/anon-record.ilo— 9/9 passcargo test— all tests pass (pre-existingbody_is_thin_bootstrapfailure is unrelated to this PR and already present onmain)Follow-ups
{name:t}where a named record with anamefield is expected (structural subtyping)withadding new fields to anonymous records is currently permitted by the type checker; may want to restrict or document_typesentinel if needed for downstream toolingCloses ILO-54
🤖 Generated with Claude Code