-
Notifications
You must be signed in to change notification settings - Fork 11
Description
We currently support adding Equatable to types that adopt Hashable:
@Equatable
struct User: Hashable {
let id: Int
@EquatableIgnored var name = ""
}Will then synthesize an == operator and a hash function.
Product engineers might choose to adopt Hashable on an extension:
@Equatable
struct User {
let id: Int
@EquatableIgnored var name = ""
}
extension User: Hashable {
}Because the Hashable adoption is not part of the main declaration our Equatable macro does not "see" that we should synthesize a hash function. The swift compiler will synthesize its own. The swift compiler might synthesize a hash function that is inconsistent with the expectations of our == operator… which is the original bug we intended to fix.
One potential workaround is to synthesize a "bad" hash function if Equatable is attached to a type that does not adopt Hashable on its main declaration:
@Equatable
struct User {
let id: Int
@EquatableIgnored var name = ""
}
extension User {
nonisolated public func hash(into hasher: inout Hasher) {
fatalError()
}
}
extension User: Hashable {
}
var set: Set = [
User(id: 0)
]At runtime we will crash when attempting to insert User in Set or Dictionary. Our runtime error message might instruct product engineers that Hashable must only be adopted on the main declaration.