There's a hole in our AnyHashable implementation when it comes to what I'll 
call "pure" NSNumbers coming from Cocoa, which were instantiated using 
-[NSNumber numberWith*:] factories or @(n) syntax in Objective-C. While we 
maintain type specificity when Swift number types are bridged through NSNumber, 
NSNumbers constructed in ObjC do not necessarily remember the type they were 
constructed with or expect to be strictly used as only that type, so we resign 
to being "fuzzy" and let them bridge back to any Swift type. We however fail to 
bring this fuzziness to AnyHashable. When we construct an AnyHashable, we'll 
bring bridged NSNumbers back to their original Swift types, but we leave a pure 
NSNumber as an NSNumber, so it doesn't hash or equate with numeric values in 
Swift:

// ObjC
@import Foundation;

NSDictionary *foo() {
  return @{@(1): @"one"};
}

// Swift
let theFoo /*: [AnyHashable: Any]*/ = foo()
theFoo[1] // returns nil, ought to find the value "one"

One way to address this would be to make Swift's number types use the same 
hashing as NSNumber does. We could go so far as to switch the "custom 
AnyHashable" polarity around and coerce the Swift number types into NSNumbers 
when we put them inside AnyHashable, which would give us consistent hashing and 
fuzzy equality, but would come at a performance cost when converting a number 
to AnyHashable. We would also lose type specificity in equality for Swift 
values, since NSNumber's -isEqual: only compares numeric value, unless we 
special-cased NSNumber in AnyHashable's implementation.

If we didn't want to adopt NSNumber's hashing for Swift's types, but we were 
willing to say that all of Swift's number types produce the same hashValue for 
the same numeric value (so 12.hashValue == 12.0.hashValue == (12 as 
UInt8).hashValue, etc.), we could also go the other direction, and customize a 
pure NSNumber's AnyHashable implementation to use Swift's number hashing. We 
would still need special handling for equality of a pure NSNumber with Swift 
numbers, but maybe that's inevitable.

-Joe
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to