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-6696] Value types bridged to Objective-C must be Hashable for -isEqual: to work #49245
Comments
cc @jckarter. We have a Radar for this, right? |
I can't find it right now, but it is a known issue. |
@swift-ci create |
The problem here is that any class that overrides Defining https://bugs.swift.org/browse/SR-7284 is a related issue, dealing with the problem that NSObject subclasses are always hashable, but the Swift values they represent may not be – so sets and dictionaries bridged to Swift may contain elements that aren't Hashable. |
We've pointed out in the past that a hash value of |
That seems questionable advice to me; ideally we should not continue propagating it. The constant 0 is not really an appropriate hash value for any type that includes more than one distinct value. Such a hash value is attractive as a quick fix, but it causes more problems down the road, by defeating the entire point of hashing. For classes that might get hashed (i.e., all NSObject subclasses except perhaps those whose instances never get passed to frameworks outside the author's control), the only safe option is to implement proper hashing – i.e., to derive a hash value from exactly the same components that the class looks at in its A better advice would be that types conforming to Equatable should also conform to Hashable. Adding the extra conformance usually requires minimal effort, but it unlocks a lot more functionality, and it ensures seamless interoperability with Objective-C interfaces. |
Things are a lot better now than they used to be in that regard, but it's really common to just want to make something Equatable, and not need to put it in an NSDictionary or NSSet. Right now we have a usability trap where equality silently fails. I think it's worth replacing that with a usability trap that hashing is bad. How about splitting the difference: warning (once per type) if the bad |
That could work! Although I wonder how much of an overkill it would be if we would produce a compile-time warning whenever an Equatable but not Hashable type is wrapped in a _SwiftValue. |
I don't think we know when that happens. Consider |
Attachment: Download
Environment
Xcode Version 9.2 (9C40b)
Default toolchain
Additional Detail from JIRA
md5: b462c8bc866585f5bb9e00b013767a87
Issue Description:
When using a Swift value type in Objective-C, it seems that the value type must be Hashable in order for isEqual: to call through to the underlying Swift == implementation:
outputs:
Ideally I'd like something Equatable bridged to Objective-C to respond to isEqual: by calling the underlying == implementation. If Hashable is a hard requirement for some reason, then I guess this is a request for clearer documentation around that fact.
I've attached an Xcode project with the above code. I'm pretty sure it happens when building outside of Xcode but I didn't bother figuring out how to use a bridging header from the command line.
The text was updated successfully, but these errors were encountered: