Currently `Comparable`

inherits from `Equatable`

, but does not provide a default implementation for `==`

, so the compiler tries to synthesize one composed of member-wise `==`

s. This leads to a problem where if a type's `<`

is not composed of member-wise inequalities, then `<`

, `>`

, and `==`

all evaluate to `false`

for some pairs of values. For example:

```
struct Length {
enum Unit: Double, Comparable {
case mm = 0.001
case m = 1
case km = 1000
case banana = 0.178 // according to bananaforscale.info
}
let magnitude: Double
let unit: Unit
static func < (lhs: Self, rhs: Self) -> Bool {
lhs.magnitude * lhs.unit.rawValue < rhs.magnitude * rhs.unit.rawValue
}
}
let aBanana = Length(magnitude: 1, unit: .banana)
let anotherBanana = Length(magnitude: 0.178, unit: .m)
print(aBanana < anotherBanana) // prints 'false'
print(aBanana > anotherBanana) // prints 'false'
print(aBanana == anotherBanana) // prints 'false'
```

Logically, a = b iff a â‰® b and a â‰Ż b, so one would reasonably think that `aBanana == anotherBanana`

, because neither the `<`

nor the `>`

evaluates to `true`

. This is also the source of a SwiftPM bug where one package version can be neither equal to nor greater/lesser than another at the same time.

Additionally, the current behaviour does not match `Comparable`

's documentation:

Types with Comparable conformance implement the less-than operator (

`<`

) and the equal-to operator (`==`

). These two operations impose a strict total order on the values of a type, in which exactly one of the following must be true for any two values`a`

and`b`

:

`a == b`

`a < b`

`b < a`

I tried to think of an example where the status quo is preferred, but can't come up with a good one.

Adding a default implementation of `==`

to `Comparable`

like this:

```
extension Comparable {
@inlinable
static func == (lhs: Self, rhs: Self) {
!(lhs < rhs || lhs > rhs)
}
}
```

is silently source breaking, but likely the sources it breaks are already incorrect.

What does everyone think?