This entire suite was copied wholesale from SwiftObjectNSObject.
Some of it may not apply, very little of it has been critically
evaluated. But it should help avoid unexpected changes in SwiftValue behavior.
Update PR #68720 with lessons learned in reviewing #69464
Background:
* SwiftValue can expose Swift value types (structs/enums)
to ObjC by wrapping them in an Obj-C object on the heap
* SwiftObject is the Obj-C type that Swift class objects all
inherit from (when viewed from Obj-C). This allows arbitrary
Swift class objects to be passed into Obj-C.
History:
* PR #4124 made Obj-C `-hash` and `-isEqual:` work for SwiftValue for Hashable Swift types
* PR #68720 extended SwiftValue to also support Equatable Swift types
* PR #69464 added similar support to SwiftObject
In the process of working through #69464, we found a better way
to handle an ObjC request for `-hash` for a type that is Swift
Equatable but not Hashable. This PR updates SwiftValue to use
the same approach. The approach considers three cases:
1. A Hashable type can forward both `-hash` and `-isEqual:` to
the Swift object.
2. A type that is neither Equatable nor Hashable can implement
`-isEqual:` as the identity check and `-hash` as returning
the address of the object in memory.
3. A type is that Equatable but not Hashable is more complex.
In this last case, we can easily forward `-isEqual:` to the
Equatable conformance but ObjC also requires us to
always provide a compatible `-hash` implementation.
The only way to do this is to have `-hash` return a constant,
but that is a very bad idea in general, so we're also including
a log message whenever we see a request for `-hash` on
a Swift value that is Equatable but not Hashable.
To limit performance problems from the logging itself, we
emit the log message only once for each type.