When Swift 5.7 drops, what will be the difference between AnyHashable and any Hashable?

When Swift 5.7 drops, what will be the difference between AnyHashable and any Hashable? Or for that matter, AnyView and any View? Or AnyPublisher vs. any Publisher?

I'm writing a blog about how to use protocols in Swift and just looking to hopefully explain what's sure to be a confusing point going forwards. What would be the pros/cons of using these new existentials vs. the type-erasing wrappers that we currently use? Thanks.

1 Like

Constrained existential still lack a key feature that would allow them to completely replace most hand-implemented type erasers: they don’t conform to the protocol of which they’re an existential.

So you couldn’t have a Set<any Hashable>, or return any View from var body, because those require Hashable and View conformance. Whereas AnyHashable and AnyView do conform to those protocols.

The reason for this is that the protocol conformance needs some business logic to be implemented. To give any Comparable a Comparable conformance, you need to implement <. You could imagine a hypothetical syntax where you could write extension any Comparable: Comparable { /* implement == and < */ } but a human has to specify the implementation (which could first compare the types, then open the values when the types are equal and compare those).

11 Likes

Is this correct then:

  • some Foo - static type, guaranteed to conform to Foo
  • any Foo - dynamic type, guaranteed not to conform to Foo (unless Foo is an @_marker protocol or an Obj. C protocol without static and/or initializer requirements)

Is that accurate or not?

any Error conforms to Error, through special hardcoding today. I don’t think nonconformance is a fundamental property of any Foo, just that today most any Foo do not conform to Foo. In some cases there are conformances that make sense but can’t be implemented today; in some a conformance wouldn’t make sense at all.

6 Likes

Is there a way to hardcode conformance, e.g.:

protocol Foo {}

extension any Foo: Foo {}

?

Not today; that would need to go through the Swift evolution process. Some questions that would have to be addressed in such a pitch:

  • How does this interact with SE-0352 Implicitly Opened Existentials?
  • Can such a conformance be added in a later OS release than the original protocol?
  • What happens if the any conformance is inconsistent with the conformance on the concrete type, and how do we teach that?