-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Add type metadata for extended existential types #42047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
rjmccall
merged 5 commits into
swiftlang:main
from
rjmccall:extended-existential-type-metadata
Mar 28, 2022
Merged
Add type metadata for extended existential types #42047
rjmccall
merged 5 commits into
swiftlang:main
from
rjmccall:extended-existential-type-metadata
Mar 28, 2022
Conversation
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
84e97bd
to
d84b32b
Compare
@swift-ci Please test |
The vast majority of generic parameters follow a simple pattern (type parameter that defines a key argument), which we can take advantage of to avoid actually representing them in type metadata: if all the type arguments is the simple pattern, and there's not more than some preset number, simply use a pre-allocated array in the runtime. Actually doing this for generic types will require some care around back-deployment, as well as finding a bit to store that we've done it. But we can at least start doing this for new ABI, such as the extended existential shape descriptors.
When we adopt C++17, we'll be able to do this with a fold expression, but this will be useful in the meantime.
d84b32b
to
57e27d5
Compare
@swift-ci Please test |
@swift-ci Please test Windows |
Some parts of the type metadata system are difficult to unit-test because they rely on structures that contain relative references, which the C compiler cannot generate. We have traditionally just relied on integration testing with the compiler. For constrained existentials, I wanted to do better, so I spent a few days hacking up this little system which can generate graphs of objects with relative references to one another. Currently it's missing the ability to generate a lot of things which I didn't need in order to adequately test the metadata system for constrained existentials.
The immediate use case is only concretely-constrained existential types, which could use a much simpler representation, but I've future-proofed the representation as much as I can; thus, the requirement signature can have arbitrary parameters and requirements, and the type can have an arbitrary type as the sub-expression. The latter is also necessary for existential metatypes. The chief implementation complexity here is that we must be able to agree on the identity of an existential type that might be produced by substitution. Thus, for example, `any P<T>` when `T == Int` must resolve to the same type metadata as `any P<Int>`. To handle this, we identify the "shape" of the existential type, consisting of those parts which cannot possibly be the result of substitution, and then abstract the substitutable "holes" as an application of a generalization signature. That algorithm will come in a later patch; this patch just represents it. Uniquing existential shapes from the requirements would be quite complex because of all the symbolic mangled names they use. This is particularly true because it's not reasonable to require translation units to agree about what portions they mangle vs. reference symbolically. Instead, we expect the compiler to do a cryptographic hash of a mangling of the shape, then use that as the unique key identifying the shape. This is just the core representation and runtime interface; other parts of the runtime, such as dynamic casting and demangling support, will come later.
57e27d5
to
148357f
Compare
@swift-ci Please test |
@swift-ci Please test Windows |
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.
The immediate use case is only concretely-constrained existential types, which could use a much simpler representation, but I've future-proofed the representation as much as I can; thus, the requirement signature can have arbitrary parameters and requirements, and the type can have an arbitrary type as the sub-expression. The latter is also necessary for existential metatypes.
The chief implementation complexity here is that we must be able to agree on the identity of an existential type that might be produced by substitution. Thus, for example,
any P<T>
whenT == Int
must resolve to the same type metadata asany P<Int>
. To handle this, we identify the "shape" of the existential type, consisting of those parts which cannot possibly be the result of substitution, and then abstract the substitutable "holes" as an application of a generalization signature. That algorithm will come in a later patch; this patch just represents it.Uniquing existential shapes from the requirements would be quite complex because of all the symbolic mangled names they use. This is particularly true because it's not reasonable to require translation units to agree about what portions they mangle vs. reference symbolically. Instead, we expect the compiler to do a cryptographic hash of a mangling of the shape, then use that as the unique key identifying the shape.