[swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

Jordan Rose jordan_rose at apple.com
Thu Aug 10 18:11:20 CDT 2017



> On Aug 10, 2017, at 15:34, Tony Allevato <tony.allevato at gmail.com> wrote:
> 
> Do you mean something like this, then?
> 
> ```
> struct Foo: Equatable {
>   let x: Int
> }
> 
> func test<T: Equatable>(_ lhs: T, _ rhs: T) -> Bool {
>   return lhs == rhs
> }
> 
> extension Foo {
>   static func == (lhs: Foo, rhs: Foo) -> Bool {
>     return lhs.x % 2 == rhs.x % 2
>   }
> }
> 
> print(test(Foo(x: 5), Foo(x: 7)))  // true
> ```
> 
> That seems to work.

Ah, yes, this works in a source file. It may even work in the REPL, if the REPL delays evaluating input until it sees an actual statement. However, the original REPL transcript you pasted in would not have worked.

> 
> I just tested the Annoying example as well and yes, the version from the Annoying extension is what gets called in my implementation.
> 
> I agree with you that that seems like the correct behavior—the manually written version takes precedence over the synthesized version, even though it comes from a different protocol extension; synthesized versions should always be the last resort because they're not controlled by the user, correct?
> 
> This also seems consistent with the way regular methods are resolved if we take synthesis completely out of the equation:
> 
> ```
> protocol Fooquatable {
>   static func foo(lhs: Self, rhs: Self) -> Bool
> }
> 
> protocol Annoying {}
> extension Annoying {
>   static func foo(lhs: Self, rhs: Self) -> Bool {
>     print("annoying")
>     return true
>   }
> }
> struct Foo: Fooquatable, Annoying {
>   let x: Int
> }
> 
> func foo<T: Fooquatable>(_ lhs: T, _ rhs: T) -> Bool {
>   return T.foo(lhs: lhs, rhs: rhs)
> }
> 
> print(foo(Foo(x: 5), Foo(x: 6)))  // annoying, true
> ```
> 
> Does this seems reasonable? (Assuming I'm testing the right thing. :)

Yep, that's why I think this is the right behavior as well. It does mean that this synthesis doesn't quite behave like a usual default implementation, because that would make this code ambiguous. If we really wanted it to match that behavior we'd have to rank it like a kind of protocol extension member. I think it's okay not to do that, though.

Jordan

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170810/95768b98/attachment.html>


More information about the swift-evolution mailing list