-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Structural opaque result types #40710
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
Structural opaque result types #40710
Conversation
For a declaration that has a named opaque type, create a complete generic signature describing the opaque type that includes the specified generic parameters and any requirements within that generic parameter list. This aligns the representation of named opaque types with unnamed ('some P') opaque result types, so we get the same inference behavior. Introduce an egregious hack in type resolution to fake name lookup for the generic parameters that are specified as part of a named opaque type. This is to be replaced with the proper name lookup mechanism to find those generic parameters, such that type resolution can turn them into opaque type archetypes. There are also a number of issues with structural opaque types that are brought to the fore by named opaque types, especially the fact that OpaqueTypeDecl does not retain the mapping from specific instances of `some` to the corresponding (implicit) generic parameter, and generally assumes that the underlying type of the OpaqueTypeDecl itself is a generic type parameter. Addressing these shortcomings will benefit both features.
Generalize the implementation of opaque type declarations to maintain the "ordinal", which represents a particular "some" utterance in a structural opaque type, throughout more of the compiler. The ordinal value for a given "some" matches with the index of the corresponding generic parameter in the opaque type declaration's generic signature. To properly be able to determine the ordinal for a given "some" type representation, retain all of the "some" type representations in the `OpaqueTypeDecl` (using trailing storage), so we can map them to the proper generic parameter and ordinal later on.
…ypes. Serialize the ordinal value of OpaqueTypeArchetypeTypes and properly set the interface type of OpaqueTypeDecl on deserialization.
The "profile" of OpaqueTypeArchetypeType didn't contain the ordinal, so multiple opaque types would collide.
Opaque opaque types and record them within the "opened types" of the constraint system, then use that information to compute the set of substitutions needed for the opaque type declaration using the normal mechanism of the constraint solver. Record these substitutions within the underlying-to-opaque conversion. Use the recorded substitutions in the underlying-to-opaque conversion to set the underlying substitutions for the opaque type declaration itself, rather than reconstructing the substitutions in an ad hoc manner that does not account for structural opaque result types.
Use the generic signature and substitution map of `OpaqueTypeDecl` to emit type metadata for each opaque generic parameter (rather than only the "underyling type") and each conformance requirement on an opaque generic parameter (or dependent member thereof) that needs a witness table. Fix a bug where opaque result type metadata would miscount the number of witness tables, because it counted conformance requirements without accounting for `@objc` and marker protocols that don't have witness tables.
Remove the error that prevented the use of multiple opaque result types, which was the remaining blocker for SE-0328's structural opaque result types. Add some type checking tests for this feature, and customize the diagnostics so they describe *which* opaque result type failed to match when indeed there is a failure.
Replace shallow checks for `OpaqueReturnTypeRepr` with calls to `hasOpaque`, which ensures that we consider opaque result types in structural positions.
We weren't using the ordinal value at all, but instead had a hard-coded zero.
@swift-ci please test |
@swift-ci please test source compatibility |
Build failed |
Build failed |
@swift-ci please smoke test |
Woohoo! |
Once you land this, I'm going to look into getting |
The key complication is in https://github.com/apple/swift/blob/main/lib/AST/ASTContext.cpp#L4321-L4345. I mostly have named opaque result types (with explicit generic parameters) working, except that both #40714 and non-trivial named opaque result types rest on figuring out this representational issue. |
@swift-ci please smoke test |
1 similar comment
@swift-ci please smoke test |
The first generic parameter of an `OpaqueTypeDecl` was still being used as the "underlying" interface type of the opaque type, which is incorrect for both structural and named opaque result types. Eliminate this notion, because the (declared) interface type already has the correct structure. Only ABI checking depended on the old "underlying" type, so rework it to instead substitute into properly for structural opaque result types as well. Deserialization required a small adjustment to eliminate a cycle because the interface type of an `OpaqueTypeDecl` involves opaque archetype types, which reference the declaration itself... so deserialize the interface type later, now that it's correct.
@swift-ci please smoke test |
@swift-ci please smoke test macOS |
@swift-ci please smoke test Linux |
Implement the remainder of SE-0328 "Structural opaque result types". This includes:
Implements rdar://51723717