Is there a way to deprecate public APIs for library clients only?

So after working though this for a bit, I realised a couple of things:

  1. What I really want is to deprecate this API based on the client's minimum supported Swift language version.

  2. As it happens, package declarations include a swiftLanguageVersions property, which gets passed to the compiler. For some reason, this is an array rather than a minimum version, but whatever.

  3. I had forgotten to set this, and since I want my library to only use 5.3 language features (unless I opt-in to a newer version via #if swift), I set it to [.version("5.3")].

  4. swift build then correctly passes this to the compiler as -swift-version 5.3. Xcode doesn't, and passes -swift-version 5 instead. Because Xcode.

  5. Actually it doesn't even matter, because the swift compiler doesn't have a language mode 5.3:

    <unknown>:0: error: invalid value '5.3' in '-swift-version 5.3'
    <unknown>:0: note: valid arguments to '-swift-version' are '4', '4.2', '5'
    

The swift language mode properties are described by:

They're very short and, to be honest, not entirely helpful (it's pretty much "support the compiler's -swift-version argument", without a clear description of what that means). But there are hints that it was intended to allow what I'm trying to do:

This is important for packages which want to add support for a newer Swift language version but also want to retain compatibility with an older language and tools version [SE-0209]

So ultimately the conclusion I'm coming to is that SwiftPM is able to express what I want. I think the problem is that the compiler only knows about major Swift language versions (v4 vs v5, but not v5.3 vs v5.5). That means I can't deprecate something in a new minor version of the language (5.5) and keep compiling using an older minor version (5.3). All I can tell it is "build in v5 mode".

This is kind of problem. Swift 5.0 was released in March 2019, and that every feature since then has come in a minor language version. And once Swift 6 does come, all we'll be able to say is "build in v5 mode", without saying whether we mean 5.1, 5.3, 5.5, etc.

1 Like