Skip to content

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

Merged
merged 14 commits into from
Jan 5, 2022

Conversation

DougGregor
Copy link
Member

@DougGregor DougGregor commented Dec 28, 2021

Implement the remainder of SE-0328 "Structural opaque result types". This includes:

  • Carry the "ordinal" for opaque result types throughout the AST, serialized module files, name mangling, etc.
  • Compute substitutions for all opaque generic parameters within the constraint system and use those substitutions consistently
  • Generalize the emission of opaque type descriptor metadata to arbitrary requirements
  • Eliminate all dependencies on a single underlying generic parameter
  • Enable structural opaque result types by default

Implements rdar://51723717

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.
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - b60c885

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - b60c885

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@slavapestov
Copy link
Contributor

Woohoo!

@slavapestov
Copy link
Contributor

Once you land this, I'm going to look into getting func foo() -> some Sequence<Int> working with #40714

@DougGregor
Copy link
Member Author

Once you land this, I'm going to look into getting func foo() -> some Sequence<Int> working with #40714

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.

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

1 similar comment
@DougGregor
Copy link
Member Author

@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.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test macOS

@DougGregor
Copy link
Member Author

@swift-ci please smoke test Linux

@DougGregor DougGregor merged commit 43324e8 into swiftlang:main Jan 5, 2022
@DougGregor DougGregor deleted the structural-opaque-result-types branch January 5, 2022 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants