-
Notifications
You must be signed in to change notification settings - Fork 10.5k
RequirementMachine: Protocol typealias support #41333
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
slavapestov
merged 13 commits into
swiftlang:main
from
slavapestov:rqm-protocol-typealiases
Feb 13, 2022
Merged
RequirementMachine: Protocol typealias support #41333
slavapestov
merged 13 commits into
swiftlang:main
from
slavapestov:rqm-protocol-typealiases
Feb 13, 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
6a0cac0
to
3978d40
Compare
…erm longer I'm about to change the reduction order so that terms with more name symbols always order after terms with fewer name symbols, so for example [P].A > [P:T].[Q:U].[R:V] This will be used to implement protocol typealiases.
…symbols first We want a term with more name symbols to order after a term with fewer name symbols, even if the term with more name symbols is shorter. That is, [P].A > [P:X].[Q:Y].[R:Z] This is in support of handling protocol typealiases.
There are two kinds of protocol typealiases: 1) The underlying type is a type parameter. These rules look like [P].A => X where X is the underlying type. 2) The underlying type is a concrete type. These rules look like [P].A.[concrete: C] => [P].A. The isProtocolTypeAliasRule() predicate detects both cases and returns the type alias name ('A', in the above examples). For now it's not used anywhere, since we don't actually introduce these rules for any reason.
Now that we can detect protocol typealias rules, collect and keep track of them so that they can be recorded in protocol requirement signatures. For now, this is all NFC since nothing introduces such rules into the rewrite system, except for invalid requirements which are diagnosed anyway.
Introduces rewrite rules for typealiases defined inside the protocol itself. Typealiases defined in protocol extensions do not participate in the rewrite system, except for when they have the same name as an associated type, as per the weird rule codified in the TypeAliasRequirementsRequest for GSB compatibility.
…irementSignature type The RequirementSignature generalizes the old ArrayRef<Requirement> which stores the minimal requirements that a conforming type's witnesses must satisfy, to also record the protocol typealiases defined in the protocol.
…uirement signatures When building a rewrite system for a generic signature or protocol, we would add requirements from the requirement signature of every protocol dependency. Now, also add protocol typealias rules as well.
…() to allow protocol typealias rules
3978d40
to
fabe3bd
Compare
@swift-ci Please smoke test |
@swift-ci Please test source compatibility |
This was regressing a couple of validation tests after the seemingly-unrelated introduction of protocol typealias support.
fabe3bd
to
0deacdc
Compare
@swift-ci Please smoke test |
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.
While you could already reference protocol typealiases from contexts where type resolution is downstream of generic signature minimization, referencing protocol typealiases from
where
clauses is special because those protocol typealises must participate in the rewrite system.The way this works is that a protocol typealias introduces a rewrite rule:
[P].A => X
whereP
is the protocol,A
is the name of the typealias andX
is the type term for the underlying type.[P].A.[concrete: C] => [P].A
, whereC
is the concrete type.Indeed, a protocol typealias looks like a lot like an associated type together with a single same-type requirement, with the major difference being that no associated type symbol is introduced. Since a protocol typealias is not canonical -- we always want to replace it with its underlying type -- the reduction order must be tweaked.
Previously a shortlex order was used, where terms were first compared for length, and then two terms with the same length were compared pairwise. To ensure that typealises are always canonicalized away, the order will now first compare the number of name symbols on both sides; a term with more name symbols always orders after a term with fewer name symbols, even if it is shorter.
The GenericSignatureBuilder would perform name lookups into protocols to resolve typealiases as needed. The RequirementMachine builds the rewrite system in one shot, so it would need to page in all members of every deserialized protocol to find typealiases. Instead, we extend the protocol requirement signature to use a new
RequirementSignature
type that stores typealias information in addition to theArrayRef<Requirement>
that was stored before. This new representation round-trips through serialization.Another change here is only protocol typealiases defined in the protocol itself participate in the rewrite system. Typealiases in protocol extensions can still be referenced from contexts downstream of generic signature minimization, but they cannot be referenced from
where
clauses with the Requirement Machine.Protocol typealias rewrite rules participate in minimization but are tracked separately from "ordinary" requirements.
One funny quirk is that the rule introduced for a protocol typealias is indistinguishable from a
where
clause referencing an invalid associated type:However, this "invalid where clause" spelling will be diagnosed after the generic signature is built when we perform the second pass over the where clause, so this isn't a backdoor to spelling a typealias in a new way.
Fixes rdar://problem/88134748.