Atomic is only available in iOS 9999 or newer

I've downloaded the latest nightly toolchain to try out Swift Atomics, but I get this error:

'Atomic' is only available in iOS 9999 or newer

I can get around this by annotating required section of code with @available, but I am wondering about 2 things now:

  1. Is Atomic going to require runtime support?
  2. If not, why I am getting this error?

Somewhat related to above, is it known in which version of Swift Atomics will ship?

Any new additions to the Swift standard library for the release under development (5.11 in this case) have @available attributes that mark them available in version 9999 of each Apple platform. The placeholder 9999 is used because these APIs are not yet available in any runtime distributed by Apple and there is therefore no actual version that can be safely specified. Once the APIs do become part of an official release, 9999 will be replaced with the actual version of the operating system they were released with.

If you just want to experiment with writing code using the API surface of Atomic you could just add corresponding @available attributes or if #available guards to the code that references Atomic.

2 Likes

The question about whether Atomic will require runtime support is interesting, though… is it a feature that could be implemented entirely with @_alwaysEmitIntoClient and compiler support?

No, the two language facilities for automatically back deploying APIs (@_alwaysEmitIntoClient and @backDeployed) can only operate on functions. Atomic and many of the other new APIs in the Synchronization module are types. Back-deploying types and other non-function Swift declarations is a very difficult endeavor that involves bespoke work in the toolchain to pull off.

3 Likes

Allan basically hit the nail on the head here, but I do want to mention that all of the atomic operations are @_alwaysEmitIntoClient but yes it's the actual types that prevent us from giving these things older availability. More specifically, these types have their own metadata and these metadata symbols are the things that have availability. It would be easy to say this type has no metadata, but that's a ton of compiler work to prevent things like passing Atomic as a generic argument, getting its metatype, putting it in an existential, etc.

I know @Joe_Groff has talked about generalizing AEIC to something like a @vendored which could support types as well, but this means you can't declare public API that uses this type outside of the defining module.

2 Likes

@vendored seems like it could work in tandem with the @backDeployed feature for types, with an implementation that provides a vendored definition of the type definition in clients that require back deployment but which favors the external definition when available. This would allow for the type to be used in public API with a new enough deployment target while still allowing it to be back-deployed for internal use. There would be the possibly-too-severe constraint on the external type definition that it can never change to become incompatible with possible vendored implementations; at first thought that seems like it's effectively like being @frozen but there may be other consequences as well.

2 Likes

I see, thank you!

Is there an easy way to run code using atomics on my current OS?

You can temporarily add -Xfrontend -disable-availability-checking to an executable you're building to ignore these issues. This assume you are going to run said executable against the toolchain's new dylibs where these symbols are present.

2 Likes