Commit af8423d
committed
[stdlib][SR-14665] add default
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)== implementation for Comparable
1 parent 17d3335 commit af8423d
1 file changed
Lines changed: 25 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
174 | 184 | | |
175 | 185 | | |
176 | 186 | | |
| |||
217 | 227 | | |
218 | 228 | | |
219 | 229 | | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
220 | 245 | | |
0 commit comments