...but why won't it let you override the operator when both arguments are Optional? Both lhs and rhs are clearly bound to the same type. It is because all these cases should be implicitly handled? I'm not sure what triggered me to implement them in the first place, likely a misunderstanding of a compiler error. I removed these from my codebase with no ill side effects so a big thank you ;-)
And while an operator boils down to a function and you can normally ⌘-Click on functions to know which override is being used, AFAIK that shortcut doesn't seem to work on operators. Nor does it seem possible to use Show Callers... or Find Call Hierarchy to inspect uses across the codebase. Again... toolchain issues more than compiler issues, but confusing nonetheless.
Indeed I removed those entirely after comments from someone else... I cannot remember why I implemented those, but I must have seriously misinterpreted a compiler error.
The fact that Swift handles comparison between optional and non-optional automatically is both a welcome discovery and unexpected (to me anyway). Swift wants you to think carefully about optional values, which is great when compared to our Obj-C past (it's OK to message nil, everyone does it!). It seems surprising that Swift would give you this behavior for free: "When you compare a value with an optional of the same type, we'll return false if the optional value isn't available, otherwise we'll unwrap for you, compare the value and return the result of that comparison".
It isn’t implicitly unwrapping one value; it’s implicitly wrapping the other, and then doing a sensible comparison between two values of the same type, Optional<Whatever>.
You should be aware that the builtin == operator isn’t equivalent to your custom one. Semantically that is a good thing I think.
Specifically, your operator overload made the following code no longer work as I’d expect:
let thing1: String? = nil
let thing2: String? = nil
assert(thing1 == thing2) // normally fine, but not with the custom operator overload
nil truly is of course equal to nil, but your code short circuited to return false if LHS is nil (due to the unwrapping via !, which would otherwise crash).
Edit: actually the above is not true, because your overload only targeted one of the sides (not both) being Optional. So semantically the overload you wrote does actually make sense, since the non-optional side cannot be nil
I'm adding this here almost purely out of desperation and for other poor souls who might stumble through a search. Xcode Beta 5 and 6 miraculously restored normal compilation performance to my Swift sources, to the point where I felt I could finally stop worrying about what I was writing (e.g. float literals rather than Double(...) wrapped literals).
Xcode Beta 7 just ruined everything again. Compilation is unbearably slow and will often get stuck – seemingly indefinitely – on certain files, requiring a Stop + Build to get past these deadlocks.
If others are having similar symptoms, and know of solutions, I would be very grateful to hear them.
You can set a memory limit for the type checker. I forget the exact flag. We’ve used this at my employer as a proxy for compilation speed for a long time, with the assumption that memory usage is correlated with time taken to type check, but I don’t know if that’s always correct.