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
[SR-6650] Conditional conformance not identifying protocol extension implementation #49199
Comments
cc @DougGregor |
Comment by Edison Santiago (JIRA) Just tried to compile it with the new Xcode 9.3 Beta and still got the same error =/ Am I doing something wrong? Wasn't that supposed to work this way? |
The problem here was the compiler was "accidentally" not implying conformances, that is, writing a conformance to a child protocol wouldn't automatically create the conformance to the parent. As of #15268 (which is included in the 2018-04-04 development snapshot), the compiler gives even better errors:
It also includes some (currently slightly syntactically incorrect, but fixing them now) fixits that offer two options for an appropriate conformance. Additionally, the
As the diagnostics have dramatically improved, I'm going to tentatively closed this as resolved. What do you think edisonlsm (JIRA User)? |
Comment by Edison Santiago (JIRA) Hello @huonw![]( Thanks for the clarification and the fixes) Just downloaded the 2018-04-04 toolchain and the new compiler error message made it much better![]( Now I managed to make it work just by following the fixit and going with the first option) And it worked with the Xcode 9.3 default Swift, yay 😃
Since I have a lot of protocols like `UseResourceProtocol` in my code here (I only used one to illustrate the problem, but I have more), I need for the conformance to be on the extension and making it conform to `UseResourceProtocol` and `UseSpecializedResourceProtocol` solved it for me! I assumed that the conformance would be implied to the parent protocol and that's what caused my entire problem here. Is this a bug at this moment or is this the intended behavior of the language? |
It was a good assumption to make, and it was incorrect of the compiler to be so confusing when people make that assumption. Having the implied conformance is how it works for non-conditional ones, and was actually what the proposal for conditional conformances originally said. However, we realised that this behaviour may be a surprising and suboptimal in some cases, so we recently amended that proposal to change the behaviour. If you're interested in the reasoning, that pull request and the discussion thread go into some detail, and feel free to ask any questions here or on the forum. For your specific code, one could phrase the reasoning as: what if |
Attachment: Download
Environment
Xcode 9.2, Swift 4.1-dev 2017-12-19
Additional Detail from JIRA
md5: 3b53df29384c766a5be3cfc258b16e91
relates to:
Issue Description:
I've been using the Development Snapshot from 2017-12-19 to start working with conditional conformances. For some reason when using a conditional conformance on a protocol that inherits from another protocol the default implementation for the parent protocol is not recognized, but it works when using the "regular" conformance.
I have an hierarchy of protocols that implement resources on the objects that conforms to it.
I also have a hierarchy of protocols that provide code to handle this objects. The implementation for the function required by `UseResourceProtocol` is given by `UseSpecializedResourceProtocol`.
When creating a struct conforming to `UseSpecializedResourceProtocol` the code compiles as expected and the struct `UseSpecializedResource` has the implementation of `foo(t: T)` provided by the extension of `UseSpecializedResourceProtocol`.
However, when trying to make a struct conform to `UseSpecializedResourceProtocol` using conditional conformance I got a compilation error saying that UseResource<T> does not conform to `UseResourceProtocol`, the parent protocol. I receive no error about the child protocol, only about the parent.
After some testing I've discovered that making an extension of the parent protocol and conforming `UseResource<T>` to the parent protocol makes the code compile and works as expected.
After adding this extension and the conformance to the parent protocol the code compiles and a call to `UseResource<T>.foo(t:T)` calls the implementation provided by the child protocol as expected, printing "bar".
The extension of `UseResourceProtocol` is never used, but without it this extension the code does not compile.
Also, the compiler does not give any warning about the "redundance" conformance of UseResource to `UseResourceProtocol`, despite conforming to UseResource twice.
UPDATE: Just give the code one more try using the 2017-12-25 Development Snapshot and now the error messages are much clearer.
If I comment out the `UseResourceProtocol` extension (on line 38) the compiler complains that the implementation provided by `UseSpecializedResourceProtocol` is non-matching and give the suggestion of adding the implementation on the struct itself.
If I keep the `UseResourceProtocol` extension and comment out the redundant conformance of `UseResource` to `UseResourceProtocol` I get a Abort trap: 6 signal.
The `UseSpecializedResource` "regular" conformance (line 27) still works as expected, conforming to the inherited protocol even if I comment out the `UseResourceProtocol` extension.
The text was updated successfully, but these errors were encountered: