Polymorphic 'this' type#4910
Merged
Merged
Conversation
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
This PR implements polymorphic typing of
thisfor classes and interfaces as inspired by #3694. The new features are:thisin an expression within a non-static class or interface member is considered to be an instance of some class that derives from the containing class as opposed to simply an instance of the containing class.thiskeyword can be used in a type position within a non-static class or interface member to reference the type ofthis.thistype within the class (including those inherited from base classes) are replaced with the type itself.This feature makes patterns such as fluent interfaces and covariant return types much easier to express and implement. Languages such as C++, Java, and C# use a somewhat involved generic pattern to emulate this feature, as described here.
An example:
In a non-static member of a class or interface,
thisin a type position refers to the type ofthis. For example:Each subclass of the above
Entitywill have aclonemethod that returns an instance of the subclass, and anequalsmethod that takes another instance of the subclass.The
thistype is a subtype of and assignable to the instance type of the containing class or interface, but not vice-versa (becausethismight actually be a subclass). That is a breaking change, and certain code patterns that previously compiled may now need an extra type annotation:The example above now errors because the inferred return type of
getInstanceinAisthisand the inferred type ofgetInstanceinBisB, which is not assignable tothis. The fix is to add a return type annotation forgetInstanceinA.The polymorphic
thistype is implemented by providing every class and interface with an implied type parameter that is constrained to the containing type itself (except when the compiler can can tell thatthisis never referenced within the class or interface). That in particular turns a lot of previously non-generic classes into generic equivalents, causing more symbols and types to be created due to generic instantiation. The observed cost in batch compile time ranges from 0% in code that uses no classes to 6-7% in very class-heavy code.Note that this PR specifically doesn't aim to implement other parts of #3694 such as
thistype annotations for functions. Those will be covered by other PRs if we choose to implement them.