Repository navigation
Accessors fill abstract and interface fields; object-literal lambdas typed from the receiver - #719
Merged
Merged
Conversation
A getter/setter implementing `abstract prop: T`, or an interface's `prop: T`,
was read as a field: through the base a read printed null, and a class
implementing an interface field with accessors did not compile
(docs/not_impl/not_impl15.ts).
- `abstract prop: T` has no storage now: it is an abstract get/set pair
(getter only when readonly). A subclass fills it with accessors of its own,
or with a field, which gets accessors over it. A plain field filling an
abstract field used to be a second slot the base never read.
- An interface field (not optional, not function-typed) a class fills with
accessors has a slot holding the address of a {getter, setter} cell plus the
sign bit (INTERFACE_ACCESSOR_CELL_TAG). Loads and stores through an
interface field test the slot and call the accessor; RetainSlot/ReleaseSlot
skip the cell, and a store releases the value the setter took. This adds a
branch to every load and store of such an interface field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
not_impl15 (accessors filling abstract and interface fields) and not_impl28 (contextually typed lambdas in object literals) are implemented on this branch and covered by tests; the rest are dropped by request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e receiver
`const o: { w: (x: number) => number } = { w: x => x + 1 }` failed with "can't
find type by name: TGenParam_x": an object literal's function members never
saw the receiver, so an untyped parameter had no type (docs/not_impl/not_impl28.ts).
- A function member of an object literal takes its parameter types (and an
unannotated result type) from the receiver's field of that name, or its
interface's method less `this`.
- A generic call with such a literal for an argument
(`foo({ read: () => s, write: value => s = value })` for
`foo<T>(x: Computed<T>)`) infers first, with no code made, from the other
arguments and the literal's other members (an expression-bodied lambda's
type is its parameters' and its expression's); the parameter's type with
those type parameters known is the literal's receiver. One still holding a
type parameter (`U` of `w: (x: T) => U`) types the members' parameters only.
- Inference matches an interface template against an object (`Computed<T>`
from `{ read: () => string }`), and a function with no parameters infers
from its result (`() => T` from `() => string`).
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.
Two
docs/not_implitems, then the folder removed.Accessors fill abstract fields and interface fields (not_impl15)
A getter/setter implementing
abstract prop: Twas read as a field: through the base,print(b.prop)printednullandb.prop = xskipped the setter. A class implementing an interface field with accessors failed to compile ("field type not matching", or "can't find reference for field" through an abstract base).abstract prop: Thas no storage now: it is an abstract get/set pair (getter only when readonly). A subclass fills it with its own accessors, or with a field, which gets accessors over it. This also fixes a plain subclass field filling an abstract field, which used to be a second slot the base never read.{getter, setter}cell plus the sign bit (INTERFACE_ACCESSOR_CELL_TAG). Loads and stores through an interface field test the slot and call the accessor;RetainSlot/ReleaseSlotskip the cell, and a store releases the value the setter took.prop?: T) filled by accessors is an error. On 32-bit the cell must sit below 2 GB.Untyped lambdas in object literals (not_impl28)
const o: { w: (x: number) => number } = { w: x => x + 1 }failed with "can't find type by name: TGenParam_x" (never worked).this.foo({ read: () => s, write: value => s = value })forfoo<T>(x: Computed<T>)) first infers, with no code generated, from the other arguments and the literal's other members; the parameter's type with those type parameters known becomes the literal's receiver.Computed<T>from{ read: () => string }), and() => Tinfers from() => string.-mm=ownthef1shape still hits a borrow error that main gives with fully typed lambdas too; the new test isn't run under own.Tests
00class_accessor_implements_field.ts,00object_literal_contextual_lambda.ts(compile, jit,TSLANG_CORPUS).ctest -C Release: 6121/6121.main362f556) release tests built with this compiler: gc 175/175, rc and none 174/175 (1 gc-only skip), own 164/175 (11 not-own skips).🤖 Generated with Claude Code