albertbori/TestableCombinePublishers

Crash when comparing two related AutomaticallyEquatable core types.

Opened this issue · 0 comments

The following test causes infinite recursion:

enum MockError: Error, AutomaticallyEquatable {
    case foo
}

XCTAssertEqual(MockError.foo, MockError.foo)

The above code is flawed because it is already equatable by the Swift runtime without the need for AutomaticallyEquatable. Nevertheless, an infinite recursion crash is an unfortunate way to find that out.

The issue is caused by the following code which prefers the AutomaticallyEquatable implementation over the inferred simple-type equatabiilty that is built into simple Swift enums.

// check each core value type
if let lhs = lhs as? AnyHashable, let rhs = rhs as? AnyHashable {
    return lhs == rhs ? .equal : .unequal(.init(members: members, lhs: lhs, rhs: rhs))
}

Source

The correct solution may be to compare the hashes directly instead of deferring to the Swift runtime comparison for the given core type. Example:

// check each core value type
if let lhs = lhs as? AnyHashable, let rhs = rhs as? AnyHashable {
    return lhs.hashValue == rhs.hashValue ? .equal : .unequal(.init(members: members, lhs: lhs, rhs: rhs))
}