Combining hashes

Removing the hashValue requirement is not a viable option; the most we can do is to deprecate it. And even that probably requires some change to how we handle @available attributes on protocol members. In particular, getting a deprecation warning for hashValue implementations is not currently possible. (But it would be nice to get a warning in Swift 5 mode when hashValue conformance is resolved to anything other than a synthesized implementation.)

We shouldn't merely "tolerate" compiler changes; we should cherish them! The raison d'être of swift-evolution is to discuss changing the compiler in interesting new ways.

So far, I kind of assumed we can get away with just asking people to either rewrite hashValue to hash(into:) or (preferably) to just remove their custom implementation and let automatic synthesis do the work for them. Fix-its would work fine for that! I think there should be two of them, so that users can select the correct option:

  • Remove hashValue (when automatic synthesis is available for the declaration context)
  • Change the hashValue signature to hash(into:), leaving the body intact, ready for manual migration. (The body shouldn't be commented out, because an empty hash(into:) implementation would compile successfully and do the wrong thing.)

A (worse) alternative to full deprecation is to silently provide a default implementation of hashValue so that the compiler starts complaining about missing hash(into:) when people forget to implement anything. That and a documentation update would painlessly cover most of the migration in the long term. However, keeping hashValue around indefinitely would clearly be a mistake; I'd prefer to force people to change existing code at some point.

The Swift test suite includes a prototype implementation of this; in a previous life, some random developer implemented essentially the same thing as an external package, and this is also what @regexident proposed in his original pitch.

I strongly believe that this approach is simply not the right choice within the stdlib. The prospect of a naming discussion alone is a really strong argument against considering this route: we already have the perfect name for hashable things! Also, auto-conforming to the new protocol would truly be a one-off compiler hack.

Hashable needs to be a single protocol -- hashValue already caused far too much confusion, and throwing a second protocol (with a worse name!) in the mix would just make things even worse.

This is a really interesting idea! It needs to be fleshed out and discussed in a separate pitch. If it was implemented in a future language version, we could probably use it to migrate some parts of Hashable synthesis into the stdlib.