Many recent threads and bug reports have focused on the intended semantic model for protocol conformances in Swift, among them:
- Crazy cross-module conformance, which explores how conflicting conformances defined in multiple modules are resolved
- Matching behavior with expectations for associated types and typealiases in constrained protocol extensions
- Ergonomics: generic types conforming “in more than one way”, that explores how conditional conformances interact with generic algorithm specialization.
When Swift implementers are faced with questions about the intended programming model for generics, they commonly respond with a focus on how generics are implemented, which, as the latter discussion shows, is not always compatible with the intended semantics. Furthermore, it makes a poor foundation for user (and especially my) understanding.
That said, having failed to clearly nail down the intended semantics independent of implementation concerns, I'd like to take a different tack here, by proposing a backward-compatible implementation model that supports the intended semantics as I understand them.
But what am I pitching, exactly? It's not necessarily that we must adopt my implementation technique for Swift, though I think it might be a big improvement. The most important thing is to form an agreement about whether the semantics implied by the technique represent the intention of the language. If so, we can then discuss whether there are other ways to achieve the desired result.
According to @Douglas_Gregor, the intention is that, at the moment a concrete type is bound to a generic parameter, we can determine all of the type's conformances to any protocols based entirely on declarations visible in the scope where the binding occurs. The idea is to capture all those conformances in a conformance table that can be used to quickly look up the witness table for any protocol modeled by the type. Protocol requirements and conformances (for existential downcasts) are then looked up by finding the relevant witness table in the conformance table. A pointer to the conformance table for any instance will be stored in a new value witness table entry.
This scheme is naturally compatible with scoped conformances and conflicting conformances in different modules: binding a type to a generic parameter (or creating an existential) in scopes with different conformances visible for that type simply results in distinct conformance tables.