Hash(into:) vs hashValue

How is this magic done? Could I achieve the same 1...4 behaviour with my foo & bar methods of my P protocol, or is this special trick baked into the compiler?

  1. I can implement just hash(into:), in this case calling hashValue calls my hash(into:).

  2. I can implement just hashValue, in this case calling hash(into:) calls my hashValue.

  3. if I do #2 I am getting a warning: 'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'C' to 'Hashable' by implementing 'hash(into:)' instead.

  4. I can implement both hash(into:) and hashValue, in this case calling each calls the corresponding methods.

It is baked into the compiler. See, for example: