Availability checking for protocol conformances

This is great!

We should add all the conformances that are currently missing from the stdlib. We're currently missing some basic things -- like Equatable/Hashable conformances for String's encoding views, or sensible CustomStringConvertible conformances for index types, etc. etc. etc. ad infinitum.

This work makes it possible to add these without worrying about newly written code that may accidentally try to rely on these in places where they aren't available.

Back deployment would allow newly written code to rely on these even if it needs to deploy on previous stable releases. For new code, conformance availability would be useful even it doesn't support back deployment -- this would "just" add a (big) delay before people can generally use these. I believe this is worse than regular function availability though, because people typically can't put things like stored property declarations behind a runtime availability check -- code deploying to 5.3 and below would be practically forced to continue declaring throwaway wrapper types just to be able to, say, create a UnicodeScalarView-keyed dictionary.

(@_alwaysEmitIntoClient has the problem that it always emits the implementation into the client module (d'oh), even if it has a recent enough minimum deployment target to be able to use a symbol. I hope the eventual non-underscored variant would allow us to declare symbol availability.)

However, we will also need to decide what to do about existing code (including existing binaries) that implement some of these conformances on their own, and back deployment could be far more important for these. We tried to discourage that on this forum, but the compiler doesn't currently emit a warning when code outside the stdlib conforms stdlib types to stdlib protocols, so we're facing a potentially significant source compatibility issue.

What's the migration path for a project that currently includes code like this?

extension String.UnicodeScalarView: Equatable {
  public static func ==(left: Self, right: Self) -> Bool {
    left.elementsEqual(right)
  }
}

I expect the duplicate conformance declaration will stop compiling when we add the same conformance to the stdlib. However, the stdlib's conformance will come with an availability declaration, so without back deployment, such projects will be forced to do a nontrivial rewrite to introduce a custom wrapper type around UnicodeScalarView.

(There is also the question what to do about code whose existing conformances conflict with the ones we'll add to the stdlib:

extension String.UnicodeScalarView: Equatable {
  public static func ==(left: Self, right: Self) -> Bool {
    String(left) == String(right)
  }
}

I think it'd be okay to have these suffer a source compatibility break, but we need to make sure to keep compatibility with binaries compiled with previously released stdlib modules.)

1 Like