Test if a type conforms to a non-existential protocol

Yeah, this is a really sticky area of the language, one where my reasoning often fails. The root of it all, I think, is that Swift extensions can express two very different things:

  1. properties of values themselves, but also
  2. properties values acquire from local assumptions in the context where they’re used.

It’s confusing that extension means both of these things.

In Dave’s example in that second link, this dynamically dispatched code:

extension P {
    static var isEquatable: Bool { false }
}

…is something that the value itself knows — “I am not equatable” — whereas this statically dispatched code (which if I understand correctly is a shadow, not an override):

extension P where Self : Equatable {
    static var isEquatable: Bool { true }
}

…is tied to something the calling context knows — “if you think I implement the Equatable protocol, then I guess I’m equatable!” Dave’s example goes haywire because the local assumptions (the static types) that could expose this isEquatable implementation don’t travel around with the value itself.

This all makes sense in terms of the language specification and implementation, but it’s hard to reason intuitively about. It feels like the Liskov Substitution Principle’s bohemian cousin.

Back to the problem at hand: I don’t think you can get things to make sense again here without doing some kind of runtime test based on metadata that lives with the value itself. Whether that’s an expensive type metadata search with is or the vtable lookup I sketched, it has to be dynamic.

1 Like