Warn when checking value for equality with itself?

When checking a value for equality with itself I don't seem to get a warning (Xcode 11.3.1) even though it indicates a logic error, considering the documentation for Equatable implies that a == a is always true. I'm assuming that the compiler doesn't currently generate a warning for this based on Xcode's behavior.

I found that I had to be lucky to be alerted:

let a = 1 // local variable
let member = 1 // member variable
let global = 1 // global scope
let ref = Reftype() // local reference variable

guard a == a else { return } // Warning: Will never be executed
guard ref == ref else { return } // No warning that the equatable contract implies that `a == a` is always `true`
guard member == member else { return } // No warning
guard global == global else { return } // No warning

It's more likely that I meant to write let a = a or a == other.a.

I suppose there's no guarantee that == will actually follow that contract, unless the optimizer takes the liberty to replace the expression with true, but it should probably still be considered a strong indication of a mistake and be brought to my attention.

Is there a reason why there's no warning?

1 Like

a == a is not always true: Double.nan != Double.nan, and checking a == a is one way of checking that a isn't NaN.


It’d probably still be better to use isNaN, though. I think this would be a reasonable warning to add for all the built-in comparison operators. (It’d be possible to design a general annotation for this, but the usual comparison operators are probably the most useful.)

1 Like

To be extra clear, I'm not asserting that a == a is always true, I'm just paraphrasing the documentation:

/// Since equality between instances of Equatable types is an equivalence
/// relation, any of your custom types that conform to Equatable must
/// satisfy three conditions, for any values a, b, and c:
/// - a == a is always true (Reflexivity)

...with the assumption that this also applies to built-in types like Double despite only mentioning "your custom types".

I'm not suggesting that e.g. guard a == a else { ... } should always generate an "unreachable code" warning -- the examples I gave were just to illustrate how many planets had to align before you got any sort of heads-up.

1 Like