Very confused about some compiler warnings related to protocols—bugs or intended?

I'm not sure what you mean here; only types conform to protocols, not instances.

The function type(of:) gives you the dynamic type of a value. This is distinct from the static type.

The distinction between the dynamic type and the static type is not an "under the hood" matter. It is part of the user-facing semantics of Swift.

In the general case, it is impossible to conform every existential type to its own protocol automagically. This is not a limitation of Swift.

Consider the Comparable protocol:

You can conform type A to Comparable, providing an implementation such that (a1 < a2) == true. I can conform type B to Comparable, providing an implementation such that (b1 < b2) == true. However, if the existential type Comparable conforms to itself, then that implies we could write:

let a1c = a1 as Comparable
let b1c = b1 as Comparable
print(a1c < b1c)
// If Comparable conforms to itself, then we can compare the two values.
// But what is the result?

The compiler cannot pull an implementation of such an operation out of thin air. Yes, we can arbitrarily create a rule which sorts every value of type A before every value of type B by lexical ordering of type names, but someone would need to actually make that arbitrary decision and write it out in the form of a concrete implementation of static func < for the existential type.

(Then, someone else would complain that it would be a very silly implementation, because it would imply (100 as Int) < (0 as UInt); thereby demonstrating that any reasonable implementation requires specific knowledge of the semantics of the requirement being implemented as well as of any relationships among conforming types. You can peruse the multiple revisions of AnyHashable to see how difficult it is to implement a hash value that fulfills all the required semantics.)

The same applies to static methods, initializers, and Self or associated type requirements in every protocol.

Sure, we can (and eventually should, IMO) relax the rules around which protocols can be used as existential types, change the spelling of existential types from P to any P, and even allow users to implement self-conformance by writing extension any P: P { ... }, but the implementation itself (the part that's elided here with ...) will have to be manually written. There is no "auto-synthesis" here in the general case.

10 Likes