Home > front end >  Why doesn't Swift compiler see `contains` version from Array where Element: Equatable?
Why doesn't Swift compiler see `contains` version from Array where Element: Equatable?

Time:01-19

This code does not compile:

protocol A: AnyObject, Equatable {}

class B: A {
    static func == (lhs: B, rhs: B) -> Bool {
        lhs === rhs
    }
}

class C: A {
    static func == (lhs: C, rhs: C) -> Bool {
        lhs === rhs
    }
}

let a = B()
let b = C()
let arr: [any A] = [a, b]

[1, 2, 3].contains(1) // OK

arr.contains(b) // Error:
// Cannot convert value of type 'C' to expected argument type '(any A) throws -> Bool'
arr.contains(b as (any A)) // Same error

the contains(_:) method is declared in the Array extension where Element is Equatable, all my elements are Equatable, so why this doesn't work?

This question isn't duplicate of this one: Protocol doesn't conform to itself? because the referenced question explains why protocol doesn't conform to itself, and this question asks why the compiler is not able to see the method despite all the requirements had been met.

CodePudding user response:

I'm not sure why you get that exact error message, but the underlying reason why it won't compile is because there is no function that the compiler can use to compare a C with an arbitrary object that conforms to A for equality.

All the compiler knows about the elements of the array is that they each have a method to compare objects of their own concrete type for equality.

You'd need an == method that takes two parameters of type A to make this work and even then you'll probably come up against issues.

  • Related