0
infix operator |||

protocol OperatorRequired{
    static func ||| (lhs: Self, rhs: Self) -> Bool
}

class AdoptingClass: OperatorRequired{

}

func ||| (lhs: AdoptingClass, rhs: AdoptingClass) -> Bool{
    return true
}

Although the class itself hasn't conformed to the protocol, the above code compiles. WHY?!

This is with Xcode9.4

It seems that Xcode is being extremely smart here as if the protocol witness table is not checked at the class level rather it's checked at a global level.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • See https://stackoverflow.com/questions/35246003/why-must-a-protocol-operator-be-implemented-as-a-global-function. Defining protocol operators within types or extensions was introduced later. – Martin R Aug 22 '18 at 20:34
  • I'm aware of the change. ie before there was overloading of the `==` operator. Now it's just a static function on that type. I just don't get why/how the compiler doesn't complain. Doesn't it expect static func on that type? How does it pickup that overload and consider it a conformance to its required function? My guess is that it just expects that function **anywhere** in the entire protocol witness table which it gets. Hence no error! – mfaani Aug 22 '18 at 20:45
  • @Honey What version of Xcode are you using? The current version (9.4.1) doesn't even require you to implement the equal operator anymore for simple structures like that. Try `struct Person: Equatable { var age: Int } print(Person(age: 5) == Person(age: 5)) ` – Leo Dabus Aug 22 '18 at 21:15
  • @LeoDabus 9.1 but regardless of myXcode version, I'm just curious as to **how** it works without a compiler error. How it bypasses/fulfills a protocol requirement... – mfaani Aug 22 '18 at 21:25
  • https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md – Leo Dabus Aug 22 '18 at 21:25
  • @LeoDabus in Xcode 9.1 if you conform to it you **must** implement it. Without implementing it, you will get a compiler error. Though if you implement it globally it works. I conclude that just adopting the protocol is not enough. You must conform. Yet it seems you can also conform globally. My question is how does global conformance work?! – mfaani Aug 22 '18 at 21:28
  • @MartinR I made an edit. Please see – mfaani Aug 22 '18 at 21:37
  • @LeoDabus I made an edit. Please see – mfaani Aug 22 '18 at 21:37
  • The class conforms to the protocol because `AdoptingClass ||| AdoptingClass` is implemented. It doesn't matter if it's outside the class declaration, it's somewhere. Swift is smart enough to find it. – EmilioPelaez Aug 23 '18 at 00:03
  • @EmilioPelaez yes. I wanna understand _how_! – mfaani Aug 23 '18 at 01:00
  • Just like it does when checking conformance with any other protocol, it verifies that a list of functions with a given signature and matching scope exist, and if they all do, the protocol is being conformed to. If you want to know the specifics, Swift is open source and it's on Github. – EmilioPelaez Aug 23 '18 at 01:17
  • @EmilioPelaez can you point exactly which part of Swift repo? I wasn't able to find anything in your comments that would point me in the right direction or add something new – mfaani Aug 23 '18 at 02:00
  • 1
    Operators are a special case when it comes to name lookup – the compiler performs an unqualified lookup, which can find candidates at the source file scope as well as type scope. See for example the code [to find a witness for an operator](https://github.com/apple/swift/blob/2e12d6becd07671e15f69a2a3b9a34dee65c0aa8/lib/Sema/TypeCheckProtocol.cpp#L935-L946) requirement (a "witness" being an implementation that satisfies the requirement) – it calls through to `lookupUnqualified` for operators (a bit of a rabbit hole, but for operators it'll eventually end up searching the `SourceLookupCache`) – Hamish Aug 23 '18 at 13:38
  • (if you really want to dig into in the source code, I would highly recommend cloning the repo and doing a `./utils/build-script -R --xcode` to get an Xcode project, which will let you jump to definition, find callers and all that good stuff – note that the initial building of the project takes a good few hours tho) – Hamish Aug 23 '18 at 13:48

0 Answers0