Swift 6 has a bunch of changes that will change the way we will use Swift in the future, with some of them being breaking changes. Wouldn’t it be handy if we could try out some of these upcoming features ahead of their release, so we can evaluate the impact they will have on our codebase and can start amending our code already? Good news: there is!
With SE-0362 having been implemented in Swift 5.8, we can now opt-in into certain Swift features ahead of their release, given they’ve been already implemented in the used toolchain version, in a similar fashion as we previouly could with SWIFT_STRICT_CONCURRENCY
.
By adding the new compiler flag -enable-upcoming-feature
and appending the feature flags we would like to enable to the “Swift Compiler - Custom Flags” section in Xcode, the compiler will enable the selected features for us. For example, if we wanted to enable existential any and strict concurrency checking, we could provide the compiler with this flag: -enable-upcoming-feature ExistentialAny StrictConcurrency
. StrictConcurrency
here is equivalent to -warn-concurrency
, as it exists in Swift 5.7 and earlier.
Currently, these flags are available:
Evolution Proposal | Feature Flag |
---|---|
SE-0274 | ConciseMagicFile |
SE-0286 | ForwardTrailingClosures |
SE-0335 | ExistentialAny |
SE-0337 | StrictConcurrency |
SE-0352 | ImplicitOpenExistentials |
SE-0354 | BareSlashRegexLiterals |
Having these feature flags available will certainly make it a lot easier to be prepared for future language versions, and not be as surprised about breaking changes. I suggest enabling them one by one and seeing what they’ll flag in your codebase. It might be surprisingly lot.
Going Further
The same proposal also added a new hasFeature
compiler directive that allows us to conditionally use new Swift features, while at the same time still being able to compile our codebase with an older compiler. This can be useful if you want to update your codebase to be ready for when Swift 6 ships to compile with these new features, while still being able to build your code with an older compiler version. Or maybe we would simply like to use these features. Living on the edge!
#if hasFeature(ImplicitOpenExistentials)
f(aCollectionOfInts)
#else
f(AnyCollection<Int>(aCollectionOfInts))
#endif
We can even opt into these new language features when we’re developing for a SwiftPM target, as a new function has been added to SwiftSetting
that will allow us to tell SwiftPM about the upcoming features we would like to have enabled:
extension SwiftSetting {
public static func enableUpcomingFeature(
_ name: String,
_ condition: BuildSettingCondition? = nil
) -> SwiftSetting
}
For a more structured and complete overview of available flags, including explanations of what a certain flag does what, I can highly recommend SwiftyFlags.