<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 10, 2017, at 15:34, Tony Allevato <<a href="mailto:tony.allevato@gmail.com" class="">tony.allevato@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">Do you mean something like this, then?</div><div class=""><br class=""></div><div class="">```</div><div class=""><div class="">struct Foo: Equatable {</div><div class=""> let x: Int</div><div class="">}</div><div class=""><br class=""></div><div class="">func test<T: Equatable>(_ lhs: T, _ rhs: T) -> Bool {</div><div class=""> return lhs == rhs</div><div class="">}</div><div class=""><br class=""></div><div class="">extension Foo {</div><div class=""> static func == (lhs: Foo, rhs: Foo) -> Bool {</div><div class=""> return lhs.x % 2 == rhs.x % 2</div><div class=""> }</div><div class="">}</div><div class=""><br class=""></div><div class="">print(test(Foo(x: 5), Foo(x: 7))) // true</div></div><div class="">```</div><div class=""><br class=""></div><div class="">That seems to work.</div></div></div></blockquote><div><br class=""></div><div>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.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div>I just tested the Annoying example as well and yes, the version from the Annoying extension is what gets called in my implementation.<div class=""><br class=""></div><div class="">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?</div><div class=""><br class=""></div><div class="">This also seems consistent with the way regular methods are resolved if we take synthesis completely out of the equation:</div><div class=""><br class=""></div><div class="">```</div><div class=""><div class="">protocol Fooquatable {</div><div class=""> static func foo(lhs: Self, rhs: Self) -> Bool</div><div class="">}</div><div class=""><br class=""></div><div class="">protocol Annoying {}</div><div class="">extension Annoying {</div><div class=""> static func foo(lhs: Self, rhs: Self) -> Bool {</div><div class=""> print("annoying")</div><div class=""> return true</div><div class=""> }</div><div class="">}</div><div class="">struct Foo: Fooquatable, Annoying {</div><div class=""> let x: Int</div><div class="">}</div><div class=""><br class=""></div><div class="">func foo<T: Fooquatable>(_ lhs: T, _ rhs: T) -> Bool {</div><div class=""> return T.foo(lhs: lhs, rhs: rhs)</div><div class="">}</div><div class=""><br class=""></div><div class="">print(foo(Foo(x: 5), Foo(x: 6))) // annoying, true</div></div><div class="">```</div><div class=""><br class=""></div><div class="">Does this seems reasonable? (Assuming I'm testing the right thing. :)</div></div></div></blockquote><br class=""></div><div>Yep, that's why I think this is the right behavior as well. It does mean that this synthesis doesn't <i class="">quite</i> 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.</div><div><br class=""></div><div>Jordan</div><br class=""></body></html>