A record literal with a run-time field can be assigned to a class type (#487) - #493
Merged
Merged
Conversation
#487) `const p: P = { x: 1, items: [i, 2] }` was "invalid cast from {x:s32, items:s32[]} to P": a record with a field known only at run time is a tuple, not a constant tuple, and castTupleLikeVariants reported the tuple-to-class cast as invalid. It now makes the instance from the record's fields with castTupleToClass, as it already did for a constant record. The same goes for a record passed to a class parameter or returned as a class, and for a record variable assigned to a class, which shares its arrays with the instance. A literal assigned to a class is now built with the class's field types, as a literal assigned to a tuple or an interface already was (getTypeByFieldNameFromReceiverType): - `[i, 2]` with `let i = 7` was an `s32[]` that the cast copied into the field's `number[]` and left with no count, never freed under rc (AOT, 1M iterations: 96.5 MB, now 4.4); constant records leaked so on main as well; - `{ items: [] }` was an `any[]` the field could not take ("invalid cast from any[] to number[]"). Under own, the class takes its fields as reads out of the record's temporary slot, which own reports as borrows ("'this value' borrows a field and cannot be stored, returned or captured"): for a run-time record, where it used to report the invalid cast, and now also for a constant record, which compiled before because its arrays were copied fresh by the cast. Moving a record literal's fields into the instance is filed separately. Closes #487 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
const p: P = { x: 1, items: [i, 2] }was "invalid cast from {x:s32, items:s32[]} to P". A record with a field known only at run time is a tuple, not a constant tuple, andcastTupleLikeVariantsreported the tuple-to-class cast as invalid. It now builds the instance from the record's fields withcastTupleToClass, as it already did for a constant record. This covers a record passed to a class parameter, returned as a class, or assigned from a record variable (which then shares its arrays with the instance).A literal assigned to a class is now built with the class's field types (
getTypeByFieldNameFromReceiverType), as a literal assigned to a tuple or an interface already was:[i, 2]withlet i = 7was ans32[]that the cast copied into the field'snumber[]and then left with no count, so it was never freed. AOT, 1M iterations: 96.5 MB, now 4.4 MB. Constant records leaked this way onmaintoo.{ items: [] }: was anany[]the field could not take ("invalid cast from any[] to number[]").Under own (agreed): this shape is a borrow error, "'this value' borrows a field and cannot be stored, returned or captured", because the instance reads its fields out of the record's temporary slot. That now includes a constant record assigned to a class, which compiled before because the cast copied its arrays. Filed as #492.
New test
00record_to_class.tscovers:weakref_basicis gc-only, as onmain)--opt; the one new failure is the new test (#492)Closes #487
🤖 Generated with Claude Code