<div dir="ltr">+1, that sounds like a reasonable way to handle that situation.<div><br></div><div>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.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 15, 2017 at 9:58 AM Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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:<br>
<br>
struct Foo: Hashable {<br>
// This property is "part of the value"<br>
var involvedInEquality: Int<br>
// This property isn't; maybe it's a cache or something like that<br>
var notInvolvedInEquality: Int<br>
<br>
static func ==(a: Foo, b: Foo) -> Bool {<br>
return a.involvedInEquality == b.involvedInEquality<br>
}<br>
}<br>
<br>
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?<br>
<br>
-Joe<br>
</blockquote></div>