I was writing code earlier to make Array conform to CustomPlaygroundDisplayConvertible when it's elements are of type CGPoint. I wanted to make a different conformance for an Array when its elements are of type Optional<CGPoint> and ran into the following problem:
extension Array: CustomPlaygroundDisplayConvertible where Element == Optional<CGPoint> {
//...
}
// Error: Conflicting conformance of 'Array<Element>' to protocol 'CustomPlaygroundDisplayConvertible'; there cannot be more than one conformance, even with different conditional bounds
extension Array: CustomPlaygroundDisplayConvertible where Element == CGPoint {
//...
}
I haven't a clue why this is happening, aren't these different types?
In your case it looks innocuous, but there are many possible traps, as explained in the previous link. See also those related threads, for more context and information:
If you do that, Array’s conformance will be with the default method. The others will only ever be called if they happen to be an available static overload in a particular context. Namely:
let point = CGPoint(x: 1, y: 2)
// This will use the more‐specific overload.
print(array.playgroundDescription)
func demonstrate<T>(_ array: [T]) {
// But this will only ever use the default implementation...
print(array.playgroundDescription)
}
demonstrate(CGPoint(point)) // ...even when you probably want the specific one.
Instead, try to design it like this:
protocol CustomArrayElementPlaygroundDisplayConvertible {
// Declare whatever options you’ll use here.
var somethingRelevant: String { get }
}
extension Array where Element : CustomArrayElementPlaygroundDisplayConvertible {
var playgroundDescription: Any {
// Construct something using CustomArrayElementPlaygroundDisplayConvertible.
return map({ $0.somethingRelevant }).joined()
}
}
extension CGPoint : CustomArrayElementPlaygroundDisplayConvertible {
// Conform...
}
extension Optional : CustomArrayElementPlaygroundDisplayConvertible
where Wrapped : CustomArrayElementPlaygroundDisplayConvertible {
// Conform...
}
But you may want to do that on a wrapper instead of directly on Array, because there are pitfalls to creating a conformance of a protocol you do not control to a type you do not control.