That's an interesting point and potentially counterintuitive. Conforming to two protocols with default implementations would ordinarily require the concrete type to implement the method; in this case, you do get synthesis back because of that.
Therefore, you could work around your issue by creating an internal protocol refining Equatable
named _RestoreSynthesizedEquatableConformance
with a default implementation of ==
:
protocol _RestoreSynthesizedEquatableConformance : Equatable { }
extension _RestoreSynthesizedEquatableConformance {
static func == (lhs: Self, rhs: Self) -> Bool { fatalError() }
}
struct S { }
extension S : Strideable, _RestoreSynthesizedEquatableConformance {
func advanced(by n: Int) -> S { return S() }
func distance(to other: S) -> Int { return 0 }
}
S() == S() // true