TLTR: I am a bit surprised by this too. One might wonder if this is intentional or not.
Just providing some more details here:
In order to see why eg this:
// NOTE: No "import Cocoa" or "import Foundation" or anything.
let a = [123] == [123]
let b = [[123]] == [[123]]
print(a) // Prints true
print(b) // Prints false (why not true?)
won't work the way we might expect, we can cmd-click on the second == which will take us to the std lib definition of that ==, which reads:
func ==<T>(lhs: UnsafePointer<T>, rhs: UnsafePointer<T>) -> Bool
Ok ... so that is the best match it can find, since those are array(literal)s which might be given as args to functions taking UnsafePointers, and this is according to the rules of Swift. (Cmd-clicking on the first == will take us to the less surprising function/operator cited by the OP.)
Now let's do this:
import Foundation // <-- NOTE
let a = [123] == [123]
let b = [[123]] == [[123]]
print(a) // true
print(b) // true
and cmd-click that second == again. We'll be taken to the generated header for the ObjectiveC module and see this:
func ==(lhs: NSObject, rhs: NSObject) -> Bool
Ok ...
As you say, this "situation" would be "solved" if all Array<T: Equatable> types were conforming to Equatable. But at least in Xcode 7 beta 2 (Swift 2 beta), that doesn't seem possible. I happened to ask a question about exactly this some days ago, here:
https://forums.developer.apple.com/message/16869
Here's an alternative solution / very ugly hack for the [[...]] and [[[...]]] special cases, if anyone should be interested:
// NOTE: Will work with or without import Foundation, ObjectiveC-module's == will be used rather than these if Foundation is imported.
func ==<T : Equatable>(lhs: [[T]], rhs: [[T]]) -> Bool {
guard lhs.count == rhs.count else { return false }
for i in lhs.indices { if rhs[i] != lhs[i] { return false } }
return true
}
func !=<T : Equatable>(lhs: [[T]], rhs: [[T]]) -> Bool { return !(lhs == rhs) }
func ==<T : Equatable>(lhs: [[[T]]], rhs: [[[T]]]) -> Bool {
guard lhs.count == rhs.count else { return false }
for i in lhs.indices { if rhs[i] != lhs[i] { return false } }
return true
}
func !=<T : Equatable>(lhs: [[[T]]], rhs: [[[T]]]) -> Bool { return !(lhs == rhs) }
let a = [123] == [123]
let b = [[123]] == [[123]]
let c = [[[123]]] == [[[123]]]
print(a) // true
print(b) // true
print(c) // true