-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Handle requirement environments with concrete same-type constraints. #5857
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
Conversation
It is possible to have requirement environments in which substitution of the conforming type for Self into the requirement's signature would result in substituted same-type requirements that no longer involve type parameters. This triggered an assertion in the construction of the requiremet environement; instead, just drop the requirement because it is no longer interesting. Witness matching will simply fail later one. With this fix, it now because possible to add generic requirements to a protocol that were unsatisfiable for certain models. For example, the following protocol: protocol P { associatedtype A associatedtype B func f<T: P>(_: T) where T.A == Self.A, T.A == Self.B } can only be satisfied by conforming types for which Self.A == Self.B. SE-0142 will introduce a proper way to add such requirements onto associated types. This commit makes any such attempt to add requirements onto "Self" (or its associated types) ill-formed, so we will reject the protocol P above with a diagnostic such as: error: instance method requirement 'f' cannot add constraint 'Self.A == Self.B' on 'Self' Fixes rdar://problem/29075927.
…tative. We had two egregious errors in our handling of superclass constraints: * We were recording superclass constraints on non-representative potential archetypes, which meant they would get ignored. * When two equivalence classes got merged, we wouldn't add the superclass constraint to the representative. Drive-by fix noticed while addressing rdar://problem/29075927.
@swift-ci please smoke test and merge |
associatedtype A | ||
|
||
func f<T: P3>(_: T) where T.A == Self.A, T.A: C // expected-error{{instance method requirement 'f' cannot add constraint 'Self.A: C' on 'Self'}} | ||
func g<T: P3>(_: T) where T.A: C, T.A == Self.A // expected-error{{instance method requirement 'g' cannot add constraint 'Self.A: C' on 'Self'}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I spy another bug in Swift.tmLanguage. Thanks for unintentionally finding it! 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jtbandes , do you have Swift 3 code that was making use of this without crashing the compiler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, sorry, I'm just talking about syntax highlighting here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah! Turns out the compiler didn't crash on all examples I banned here, so I went ahead and restricted this change to Swift 4+
Oops... was this not crashing in a previous Swift? I might need to conditionalize on Swift 4 |
… mode. PR swiftlang#5857 started rejecting generic requirements that adding constraints directly to 'Self', which means the requirements would be unsatisfiable by some models. At the time that commit was merged, we had thought the compiler crashed on all instances of this problem. It turns out that, with assertions disabled, these protocols would be accepted and could be used, so downgrade the error to a 'deprecated' warning in Swift 3 compatibility mode.
It is possible to have requirement environments in which substitution
of the conforming type for Self into the requirement's signature would
result in substituted same-type requirements that no longer involve
type parameters. This triggered an assertion in the construction of
the requiremet environement; instead, just drop the requirement
because it is no longer interesting. Witness matching will simply fail
later one.
With this fix, it now because possible to add generic requirements to
a protocol that were unsatisfiable for certain models. For example,
the following protocol:
can only be satisfied by conforming types for which Self.A ==
Self.B. SE-0142 will introduce a proper way to add such requirements
onto associated types. This commit makes any such attempt to add
requirements onto "Self" (or its associated types) ill-formed, so we
will reject the protocol P above with a diagnostic such as:
While we're here, fix a longstanding issue with superclass constraints getting lost in the
ArchetypeBuilder
.Fixes rdar://problem/29075927.