You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[stdlib][SR-14665] add default == implementation for Comparable
Currently `Comparable` inherits from `Equatable`, but does not provide a default implementation for `==`, so the compiler synthesizes one composed of [member-wise `==`s](https://github.com/apple/swift-evolution/blob/main/proposals/0185-synthesize-equatable-hashable.md#implementation-details). This leads to a problem where if a type's `<` is not composed of member-wise inequalities, then `<`, `>`, and `==` can all evaluate to `false` for some pairs of values, contradicting `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`
For example:
```swift
struct Length: Comparable {
enum Unit: Double, Comparable {
case mm = 0.001
case m = 1
case banana = 0.178
}
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 oneBanana = Length(magnitude: 0.178, unit: .m)
print(aBanana < oneBanana) // prints "false", because Length's < says so.
print(aBanana > oneBanana) // prints "false", because Comparable's default implementation of >(a,b) is <(b,a).
print(aBanana == oneBanana) // prints "false", because the 2 Length instances are not member-wise equal.
```
Relevant forums discussion: https://forums.swift.org/t/add-default-implementation-of-to-comparable/48832
This bug has previously resulted in incorrect semantic version comparison in SwiftPM (swiftlang/swift-package-manager#3486 and swiftlang/swift-tools-support-core#214)
0 commit comments