<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">// ObjC</div><div class="">@import Foundation;</div><div class=""><br class=""></div><div class="">NSDictionary *foo() {</div><div class=""> return @{@(1): @"one"};</div><div class="">}</div><div class=""><br class=""></div><div class="">// Swift</div><div class="">let theFoo /*: [AnyHashable: Any]*/ = foo()</div><div class="">theFoo[1] // returns nil, ought to find the value "one"</div></blockquote><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">-Joe</div></div></body></html>