[Accepted with Modifications] SE-0376: Function back deployment

Hi all,

The language workgroup has continued discussion about SE-0376: Function back deployment after returning it for revision earlier this year and mulling over the community's additional input. After further consideration, we have decided to accept the proposal with the following modifications:

  • The attribute will be spelled @backDeployed(before:) (instead of @backDeployed(upTo:) as proposed in the second review).
  • The use of @backDeployed will not require the use of @avalilable, consistent with the language workgroup's revision request when the proposal was returned for revision after the second review.

The workgroup remains convinced by the arguments raised that, although "up to" has some existing uses in Swift to mean "up to but not including," the status of "up to" as a term of art is not conclusive enough for the exclusivity of the bound to be clear. The language workgroup also agrees that "up to" is a more awkward phrasing for the argument label than "before."

There were a myriad of other spellings for the attribute suggested in response to the language workgroup's request for further discussion. Ultimately, the workgroup was not convinced that any of the suggestions raised were so obviously clearer than @backDeployed(before:) that they justified more awkward phrasings or introducing jargon like "ABI" into the language surface. The workgroup expects that whatever spelling is chosen for this attribute, it will likely be primarily understood through the relevant documentation for the attribute rather than its meaning being totally transparent from the chosen spelling.

Since both of the modifications discussed here (the before: argument label and dropping the requirement of @available) have already received extensive discussion opportunity in prior reviews, the language workgroup has decided to accept the proposal with these modifications rather than running a third review focused solely on these minor changes.

As always, thank you to everyone for your participation in the discussion!

Freddy Kellison-Linn
Review Manager


Is there a version of the proposal with these updates? As described it doesn't really make sense to me. If I say @backDeployed(before: iOS 16) without an @available, what's the actual availability of the declaration? And was there ever a solution discussed for multiple back deployment implementations for ranges of OS versions? It's not mentioned so I assume that's unsupported?

I've updated the proposal in this pull request.

Any declaration that lacks an explicit availability attribute is implicitly available since the minimum possible deployment target for the target platform. For example, any Swift declaration without availability is understood by the compiler as implicitly available since macOS 10.9. Whether or not the declaration also has @backDeployed does not affect this.


Ah, so @available is simply not required, it's not that it can be used anyway.

Edit: Appears the PR has been merged and the linked proposal is up to date.


I'm glad to see this coming along! <3

Aw man, I'm a bit late to the party. One thing I noticed is that @available has a different meaning in a new world where @backDeployed exists. A back-deployed API is "available" to a user, as far as a user is concerned.

Ship has sailed, but I do wonder if tweaking an alternate spelling (alias?) of @available could make more clear. E.g.

extension Toaster {
  @backDeployed(since: toasterOS 1.0, *)
  @shipsWithPlatform(since: toasterOS 2.0)
  public func makeBatchOfToast(_ breadSlices: [BreadSlice]) -> [Toast] { ... }

This is consistent with the meaning of @available under this proposal—the target platform version in @available will always be earlier than the platform version in @backDeployed(before:).

ETA: and your suggested @shipsWithPlaform(since:), as far as I can tell, would actually be an alias for @backDeployed(before:), not @available.

This was discussed a few times in the various threads because it's commonly misunderstood. The @available attribute already does not always indicate ABI presence in a particular OS version. For example, some @_alwaysEmitIntoClient declarations have constrained availability because they depend on other declarations with constrained availability, and it will be the same way for @backDeployed functions. The @available attribute influences both type checking and linking, but the type checking impact is the more essential one. To give another example, in an app you might create your own type and give it an availability attribute because it uses APIs that are only available in certain releases. That doesn't mean your type is only present in OS runtimes since that release; your type isn't present in OS runtimes at all. The role of the attribute is to make sure that other code doesn't use that type unless the declarations it depends on are available.


Ah, you're right, I got it mixed up