rayx
(Huan Xiong)
1
Take Dictionary as an example, suppose I define multiple conditional conformances for it, each having a method with same signature, which one will the compiler choose when I call that method on a dict which has all conformances?
I have run into this scenario a few times. At first I just changed func name to avoid it. But I also did experiments and found compiler behaved as same as my intuition. It looks for the most specific condition. If found, it uses that method; otherwise, it throws ambiguity error.
Setup
struct Foo: Identifiable, Comparable, Hashable {
var id: UUID = UUID()
var value: Int = 0
static func < (lhs: Foo, rhs: Foo) -> Bool {
lhs.value < rhs.value
}
}
Example 1: there is a most specific condition
extension Dictionary where Value: Identifiable {
func get(id: Key) -> Element? {
print("Identifiable version is called")
return nil
}
}
extension Dictionary where Value: Identifiable, Value: Comparable {
func get(id: Key) -> Element? {
print("Identifiable&Comparable version is called")
return nil
}
}
func test1() {
let foo1 = Foo()
let foo2 = Foo()
let foos = [foo1.id: foo1, foo2.id: foo2]
foos.get(id: UUID())
}
Example 2: there isn't one
extension Dictionary where Value: Identifiable, Value: Hashable {
func get(id: Key) -> Element? {
print("Identifiable&Hashable version is called")
return nil
}
}
extension Dictionary where Value: Identifiable, Value: Comparable {
func get(id: Key) -> Element? {
print("Identifiable&Comparable version is called")
return nil
}
}
func test2() {
let foo1 = Foo()
let foo2 = Foo()
let foos = [foo1.id: foo1, foo2.id: foo2]
foos.get(id: UUID())
}
Does anyone know if this is an officially supported feature? I ask because I can't find any mention of this behavior on the net.
EDIT: Another question. What's the recommended solution in example 2 above? Is it possible to give hints to compiler somehow other than changing func name?
rayx
(Huan Xiong)
2
I should have checked SE-0143 first.
When satisfying a protocol requirement, Swift chooses the most specific member that can be used given the constraints of the conformance.
2 Likes
ole
(Ole Begemann)
3
It's worth noting that your examples are not conditional conformances because your extensions don't introduce new protocol conformances. So SE-0143 doesn't apply.
I don't know if the community has an official term for extensions of the kind:
extension Dictionary where Value: Identifiable
I guess I'd call this a constrained extension or conditional extension.
But the rules are similar to those stated in SE-0143. Given multiple overloads of the same symbol, the type checker will generally pick the most specific one that matches, or raise an error when there's ambiguity. I don't think the concrete rules are documented in a single place.
You may be able to add @_disfavoredOverload to one of the methods, but it's not an official feature.
1 Like