Why are both Equatable and Hashable explicitly declared in Swift OSS codebases?

In many Swift OSS repositories (such as swift-foundation, swift-syntax, etc.),
I noticed that types often explicitly declare conformance to both Equatable and Hashable,
even though Hashable already inherits from Equatable.

Example: Code search results · GitHub

Technically, conforming to Hashable alone should be sufficient.
I was wondering if there are specific reasons for explicitly listing both protocols.

Possible reasons I considered include:

  • To make the design intent clearer (distinguishing comparability and hashability)
  • For compatibility with certain code generation tools
  • Historical reasons

I would love to hear insights from the Swift maintainers or contributors.
Thank you very much!!

4 Likes

I've seen this in a lot of private code, also. I'd bet that most of the time it's just because something was Equatable and then, later on, needed to be Hashable, too, so someone (maybe me!) just added it without thinking through that they could simplify. I bet there are linters that can catch this.

5 Likes

indeed – digging into a couple of the examples from OP's github query, it seems that's precisely what happened here & here. personally i think explicit enumeration, while redundant, makes the code a bit more clear. i'd also be curious to hear if there are other reasons to do this one way or another – e.g. does it make anything more or less difficult for the compiler/macros/other source tooling?

2 Likes

I’ve definitely had to add redundant conformances for the sake of tooling before: Add Resolver to Factory's protocol list by bbrk24 · Pull Request #72 · Tiny-Home-Consulting/Dependiject · GitHub but that’s a bit different as the derived protocol wasn’t public in this case.

1 Like

Thanks all — these are really helpful insights!

It makes sense that redundant conformance often arises from evolution over time, or out of tooling limitations.
I also appreciate the perspective on clarity-through-explicitness, especially in teams or OSS contexts where the design intent may not be immediately obvious.

I’ll keep that in mind when reviewing or writing code going forward.