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-9753] REGRESSION: Ambiguity involving overloads and generics constrained by Error #52182
Comments
The new thing that happened is that Error-the-existential now conforms to Error-the-protocol. Hm. |
This sample code works if I change the overload to I'm not actually sure why the normal overload resolution rules don't handle this case; the overload is more specific on the It's entirely possible that the right solution here is to stop making Error-the-existential conform to Error-the-protocol in Swift 4 mode. Not having this code work in Swift 5 is kind of a shame, but it's something I can work around. I just don't want the existing code to break because Xcode was upgraded. |
If we stop making Error-the-existential conform to Error-the-protocol in Swift < 5 mode, the new `Result` type will be mostly unusable outside of Swift 5.0 mode, which is a bit unfortunate. It'll force people to either not use `Result` in APIs, or push their clients to Swift 5 mode. I think that's probably worse overall than accepting the source-compatibility regression. For reference, I found a small workaround: struct Foo<E> {
func bar(with: Foo<E>) {}
}
#if compiler(<5.0)
extension Foo where E: Error {
func bar(with: Foo<Error>) {}
}
#endif
let foo = Foo<Error>()
foo.bar(with: Foo<Error>()) |
Your workaround to "overloads in this scenario are ambiguous" is apparently "don't overload". The fix I'm actually planning on applying is just changing the name of the overload, because all the call-sites are statically known and it's a private function so I don't have API compatibility issues. But I still am concerned about existing clients not being able to upgrade their compiler without upgrading the library (especially if they're on an older version and would have to deal with breaking changes). More generally, I'm also concerned about unexpected behavioral changes resulting from Error-the-existential conforming to Error-the-protocol, in cases where I've overloaded an API for |
Ok I checked, the other resolutions in Tomorrowland that are affected by this appear to be benign. |
Okay, I think this is a case where we've made a source-incompatible change that we cannot meaningfully back out (due to the self-conformance of Swift.Error introduced in https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md.,)), and changing the overload-resolution rules here would be a significant undertaking with more fallout. It's not necessarily a bad idea, but should be done within a larger context. Given those, I'm going to close this as "won't fix" with my apologies that you'll have to adapt your code. |
Environment
Apple Swift version 5.0 (swiftlang-1001.0.45.7 clang-1001.0.37.7)
Target: x86_64-apple-darwin18.2.0
ABI version: 0.6
Additional Detail from JIRA
md5: d9e050beffdbe60baf098d7a78e86171
Issue Description:
I have a generic struct that declares a method, and an extension to this struct that overloads the method in the case where the generic parameter conforms to
Error
. This has worked fine so far, but the Swift 5 compiler rejects this as an ambiguity error. It seems to be special-casingError
somehow because this doesn't happen with other protocols. This compiler error happens even in Swift 4 mode (though I don't believe it should happen in Swift 5 mode either).This error means Xcode 10.2 cannot compile https://github.com/lilyball/Tomorrowland.
This yields
The text was updated successfully, but these errors were encountered: