Call priority of type-constrained generic functions in swift?

Viewed 134

I have the definitions:

    func compare<T>(lhs: T, rhs: T) -> Bool where T: Equatable {
        return lhs == rhs
    }
    
    func compare<T>(lhs: T, rhs: T) -> Bool where T: AnyObject {
        return lhs === rhs
    }
    
    func compare<T>(lhs: T, rhs: T) -> Bool {
        return false
    }

When I call compare on an reference type object that also conforms to Equatable, how does the compiler decide which of these functions to call?

A full accepted answer would be link to official swift manifesto explaining how the priority is done, especially when the generic conforms to two different protocols that both have specializations

1 Answers

For whatever reason, it's not ambiguous to the compiler (I consider this a bug; see below for the error I'd expect), but it is to us. So write an overload to clarify the behavior!

func compare<T: AnyObject>(lhs: T, rhs: T) -> Bool {
  lhs === rhs
}

func compare<T: AnyObject & Equatable>(lhs: T, rhs: T) -> Bool {
  compare(lhs: lhs as AnyObject, rhs: rhs)
}

func compare<T: Equatable>(lhs: T, rhs: T) -> Bool {
  lhs == rhs
}

func compare<T>(lhs: T, rhs: T) -> Bool {
  false
}
protocol ModuleName_A { }
protocol ModuleName_B { }

func ƒ<A: ModuleName_A>(_: A) { }
func ƒ<B: ModuleName_B>(_: B) { }

struct S: ModuleName_A & ModuleName_B { }

ƒ(S()) // Ambiguous use of 'ƒ'
Related