So after working though this for a bit, I realised a couple of things:
-
What I really want is to deprecate this API based on the client's minimum supported Swift language version.
-
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. -
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")]
. -
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. -
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:
- SE-0151 Package Manager Swift Language Compatibility Version, and
- SE-0209 Package Manager Swift Language Version API Update
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.