Skip to content

own: a record literal assigned to a class type is the instance (#492) - #504

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix-own-record-to-class
Oct 5, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
fix-own-record-to-class

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Under -mm=own, assigning a record literal to a class type was a borrow error ("'this value' borrows a field and cannot be stored, returned or captured"). That covered const p: P = { x: i, items: [i] } and, since #487, the constant { x: 1, items: [1, 2] } too. The literal was built in a temporary slot, and castTupleToClass read each field back out of the slot to store it into a new P. Own treats such a read as a borrow of the slot, and a borrow cannot be stored.

A literal whose receiver is a class (a declaration, a parameter or a result) is now built as the instance itself, by mlirGenObjectLiteralAsClassInstance. Each field's value is stored into the new P as it is: a value made at run time, a number, string or boolean constant, or a constant array copied to a heap array of its own (#479). Own sees fresh values moved into a new object.

This only applies when the literal's fields are exactly the class's. These cases still go through the slot and the cast, unchanged:

  • a class with a base;
  • a literal missing a field, or holding an extra one;
  • any other kind of constant field.

I checked by hand: a base class and a missing required field give the same error as before, and a missing optional field and an extra field work as before. A nested record field still hits own's existing limit on moving an object literal.

The record-variable case of 00record_to_class.ts (let r = {...}; const q: P = r;) moves into a new 00record_variable_to_class.ts. That case shares r's array, which own reports as an error by design. With it moved, 00record_to_class.ts now passes under all four models.

Gate Result
Windows full suite (Release) 3846/3846
Linux (WSL) full suite 3831/3831
DefaultLib build + its own tests.ps1 -Model, release + debug, compile + JIT gc 159/159; rc, none 158 passed + weakref_basic skipped (gc only); all "All tests passed"
own corpus, plain and --opt 00record_to_class.ts err → ok; no other flips
rc and own memory, 1M iterations (AOT), the #487 probes flat at 4.3 MB

Closes #492

🤖 Generated with Claude Code

Under -mm=own, `const p: P = { x: i, items: [i] }` - and since #487
also the constant `{ x: 1, items: [1, 2] }` - was "'this value' borrows
a field and cannot be stored, returned or captured". The literal was
built in a temporary slot, and castTupleToClass read each field back
out of the slot to store it into a new P: own takes such a read for a
borrow of the slot, which cannot be stored.

A literal whose receiver is a class (a declaration, a parameter, a
result) is now built as the instance itself
(mlirGenObjectLiteralAsClassInstance): each field's value is stored into
the new P as it is - a value made at run time, a number, string or
boolean constant, or a constant array copied to a heap array of its own
(#479). Own sees fresh values moved into a new object. Only for a
literal whose fields are exactly the class's; a class with a base, a
literal missing a field or holding an extra one, or another kind of
constant still goes through the slot and the cast, as before.

Under rc and own, 1M iterations of a record-to-class (AOT): flat at
4.3 MB.

The record-variable case of 00record_to_class.ts (`let r = {...};
const q: P = r;`) moves into 00record_variable_to_class.ts: it shares
r's array, which own reports as an error by design, and
00record_to_class.ts now passes under own.

Closes #492

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 005a9ee into main Oct 5, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-own-record-to-class branch October 5, 2026 08:01
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.

own: a record literal assigned to a class type is a borrow error ('this value' borrows a field)

1 participant