The latest release of Swift introduces support for piecemeal adoption of upcoming features, which allows developers to start using new features that will become stable in Swift 6. Additionally, it opens the way for making new features retroactively available in earlier OSes.
The main reason for Swift 5.8 to support upcoming language features is to allow developers to start prepare for the migration of their programs. This is especially relevant given the number of Swift 6 features that bring some level of source-incompatibility, says Swift team member Alexander Sandberg. Additionally, the new feature may help Apple to gather feedback from early adopters.
Upcoming feature support is controlled by a new compiler flag, -enable-upcoming-feature X
, where X
is the feature to enable. At the moment, there are four upcoming features that can be selectively enabled in Swift 5.8: concise magic file names, [forward-scan matching for trailing closures](Forward-scan matching for trailing closures), existential any, and regex literals.
To make sure an upcoming feature is actually available before using it, a new #if
check is available, #if hasFeature(ImplicitOpenExistentials)
, which can be used along with a compiler(>=x.y)
check, in case it is needed.
Swift 5.8 also introduces support for a @backDeployed
attribute aimed to make it easier to backport new capabilities to older versions of a framework. For example, a new capability can be added through an extension and annotated with both the well known @available
and the new @backDeployed
attributes:
extension FrameworkAPI {
@available(FrameworkAPIVersion 1.0, *)
@backDeployed(before: FrameworkAPIVersion 2.0)
public func newCapability(...) -> ResultType { ... }
}
In the provided example, the newCapability
function is natively available only from version 2.0 of FrameworkAPI
, but using the @backDeployed
attribute, developers can provide an implementation of that capability that can be injected into previous versions of the framework.
This new feature is meant to make it easier for developers to create resilient libraries and can only applied to functions, methods, subscripts, and computed properties. This implies, for example, that new types cannot be supported using this mechanism. Additionally, the bodies of back deployed functions must conform to the same restrictions as @inlinable
functions, e.g., they can only reference declarations that are accessible to the client, such as public
and @usableFromInline
declarations.
Another area where Swift 5.8 brings significant change is result builder implementation, which improves compile-time performance, code completion results, and diagnostics. Specifically, the new implementation leverages Swift 5.7 extended multi-statement closure inference, which enables the compiler to optimize type inference and error messages. In particular, developers will welcome the removal of several limitations on local variable declarations in result builders, such as the requirement to have an initializer, and lack of support for computed variables, observers, and property wrappers.
There are many additional changes in Swift 5.8 than what can be covered here, so do not miss the official release announcement for the full details.