Make StaticString conform to Hashable

I just realized that StaticString doesn't conform to Hashable. Is there a good reason for that? If not, we should add a Hashable conformance to it.


Presumably the hashValue can be very efficient to compute (e.g. just be the _startPtrOrData field), right?

I think it isn’t possible to add new conformances to existing Standard Library types right now:

I’ll go ahead and say it:

The Swift Evolution process never agreed to ban proposals adding conformances to existing types.

In particular, Swift Evolution never adopted a proposal for ABI stability which explicitly stated that it would prevent adding conformances for existing types to existing proposals, even temporarily.

Notably, the ABI Stability Manifesto doesn’t mention any such restriction.

The fact that Apple Inc. rushed through ABI stability for its own platforms, without even explaining to the Swift community that such a restriction on protocol conformances would be a consequence, means that the problem is entirely with Apple, not the Swift project.

Swift Evolution is free to adopt any such proposal, and if that breaks ABI stability on Apple platforms, the fault lies entirely with Apple for presumptively declaring ABI stability when it couldn’t even properly annotate the availability of protocol conformances.

Not our problem here at the open source project. Apple jumped the gun, and the open source project is not beholden to follow.


This misunderstands the relationship between the open-source evolution community and the Swift project. You are welcome to ignore implementability in your own pitch and proposal feedback, but it is a significant constraint that will always factor into the Core Team's decision-making, and it is not appropriate for you to complain about other community members who choose not to ignore it.


Can‘t we just @_alwaysEmitIntoClient the hash function for this one and call it a day? This is a serious question as I have no idea about the internals of that private attribute, but I know what it‘s used for.

I’m not complaining about any community members, and I find it quite patronizing that you would suggest otherwise.

I am stating the fact that this restriction on protocol conformances was not (to my knowledge) raised during the discussions leading up to the declaration of ABI stability on Apple platforms.

If it had been mentioned, then I for one would have strongly pushed to delay ABI stability until all the prerequisites—including the ability to annotate the availability of protocol conformances—were in place.

Imagine if another company (eg. Google, Microsoft, Amazon, Facebook) decided to declare some other sort of Swift stability on its own platforms, which also restricted the ways in which the language could evolve.

I sincerely hope that the open source Swift project would not allow one of those companies to unilaterally limit this language’s development, and it should be no different for any company regardless of its name.

Now, if a company (or anyone else) brought a proposal before Swift Evolution which included such restrictions—and those restrictions were explicitly listed within the proposal itself—and that proposal were widely supported and got accepted by the core team, then yes those restrictions would become an official part of the language.

But in this case, the restrictions were not mentioned at all until after the fact.


Any sort of ABI stability for Swift was always going to have to confront conformance availability / back-deployment. I agree that we should aim to lift this restriction as soon as we can, but for now, it's there, and it's not going anywhere.


Yes it was. You may have missed it, but Apple were well aware of it (and ABI stability on their platforms is their call to make).


It’s a little more complicated than that. For one, the hashable protocol has 3 requirements so we’d need to emit all of those accessors, but what Jordan mentions in the backward compatibility conformance topic is that the conformance is still missing. For every conformance in Swift there is a structure called the conformance descriptor that describes a particular conformance. In addition, there is also the witness table that is emitted (unless we dynamically create it at runtime as defined by the conformance descriptor...) along with every conformance. So we’d also need to emit these structures along with the protocol requirements, but I don’t think there is infrastructure right now that knows how to do that.


Right. That’s my point. ABI stability was declared without confronting those things, and it should not have been.

Thanks for the link.

That was a thread about prohibiting retroactive conformances, and the mention of availability annotations was tangential. It was not a thread about prohibiting new conformances on standard library types.

It was also not a thread about enabling availability annotations for conformances prior to declaring ABI stability.

What I’m seeing is evidence that Apple knew that ABI stability would restrict the evolution of Swift in this way, but they did not make a serious effort to make the community aware of that restriction.

Exactly. They chose to declare ABI stability without the ability to declare conformance availability. That was their call to make, and they have to live with the consequences.

It is not their call to restrict the evolution of Swift in order to cater to that decision.

Regarding the original idea: I believe StaticString should follow String's normalization rules when it implements Equatable, so comparing/hashing static strings wouldn't necessarily be faster. (Unless we store whether the string is in the correct normal form in the generated binary -- which we should definitely consider doing. This could be tricky though.)


My vague recollection is that the normal form isn't binary-stable, in which case this seems infeasible.

1 Like

No, 2 StaticString having the same content must return the same hash, even if they are declared on different library, and so have different base address.

I don't know. StaticString is a very specific class that you should never encounter unless you really need it for very special use cases. Having it behaving differently than a real String for optimisation purpose may be reasonable IMHO.

1 Like

There are some other StaticString changes which could be combined into a single proposal.


While we're at it, we should also document that StaticString contents are nul-terminated.

I'd argue against adding even more implicit pointer conversions -- in fact, we should rather work on removing the existing ones.


Open Source or not, the mainline Swift branch is Apple's, and Apple can change and restrict it as they see fit. All that the code being Open Source means is that anyone (e.g. Google) can fork it and make whatever changes they like. Ubuntu could create a fork and implement ABI on Linux if they want to.


And furthermore, the Swift Evolution process (and this forum, by extension) is precisely for discussion about that mainline branch controlled by Apple. If there were a prominent, fully divergent fork of the language, it would not be appropriate to discuss its development and evolution here.


1 Like

Slightly off-topic, but I‘d love to see mutating methods eventually added to StaticString. You should be able to combine multiple different StaticString‘s to a new StaticString.