[swift-evolution] Refining SE-0185: Should providing a custom == suppress the default hashValue?

Tony Allevato tony.allevato at gmail.com
Fri Dec 15 12:09:52 CST 2017


+1, that sounds like a reasonable way to handle that situation.

This is another one of those pitfalls that could be mitigated with
something like the "transient" attribute that was discussed in earlier
discussion threads, but that's really about a slightly different problem
statement—it would let users avoid defining an explicit implementation
entirely by giving them finer control of what gets used in synthesis. But
even if we had that capability (and the time to design and implement it),
cases would still exist where someone needs to provide an explicit ==, and
the nature of those situations implies a *high probability* that the
synthesized hashValue will be inconsistent. This is a nice lower-cost way
of taking away a possible foot-gun.


On Fri, Dec 15, 2017 at 9:58 AM Joe Groff <jgroff at apple.com> wrote:

> SE-0185 is awesome, and brings the long-awaited ability for the compiler
> to provide a default implementation of `==` and `hashValue` when you don't
> provide one yourself. Doug and I were talking the other day and thought of
> a potential pitfall: what should happen if you provide a manual
> implementation of `==` without also manually writing your own `hashValue`?
> It's highly likely that the default implementation of `hashValue` will be
> inconsistent with `==` and therefore invalid in a situation like this:
>
> struct Foo: Hashable {
>   // This property is "part of the value"
>   var involvedInEquality: Int
>   // This property isn't; maybe it's a cache or something like that
>   var notInvolvedInEquality: Int
>
>   static func ==(a: Foo, b: Foo) -> Bool {
>     return a.involvedInEquality == b.involvedInEquality
>   }
> }
>
> As currently implemented, the compiler will still give `Foo` the default
> hashValue implementation, which will use both of `Foo`'s properties to
> compute the hash, even though `==` only tests one. This could be
> potentially dangerous. Should we suppress the default hashValue derivation
> when an explicit == implementation is provided?
>
> -Joe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171215/a43ec5cb/attachment.html>


More information about the swift-evolution mailing list