As Swift evolves, it gains new features and enhancements as govered by the Swift Evolution process. Once implemented, new features become available in new versions of the tools, e.g., async
/await
was first available in the Swift 5.5 tools, and one will need to upgrade to newer tools to make use of those features. New features and enhancements must maintain source compatibility, meaning that the new Swift tools must still accept Swift code that was accepted by older Swift tools, so that Swift code written using the Swift 5.1 tools will still compile with Swift 5.5 tools and beyond. Source compatibility can have a significant effect on the overal design of features, and is explicitly part of the proposal process, but it still allows for major improvements to the language. For example, the entire Swift Concurrency effort, including async
/await
, structured concurrency, and actors, was introduced while maintaining source compatibility.
It is sometimes the case that a change that is desirable for the language will necessitate breaking source compatibility. Again, Swift Concurrency provides an example: the Sendable
checking described in SE-0302 will cause a significant number of Swift programs to be rejected due to missing Sendable
annotations. To address this issue, the Swift tools support multiple language versions. For example, the Swift 5.5 tools, support language versions 4, 4.2, and 5, whereas future Swift 6.0 tools would likely support language versions 4, 4.2, 5, and 6. The Sendable
checking will be downgraded to warnings or suppressed in existing language versions (4, 4.2 and 5), which covers all supported Swift code, then enabled as errors for future language versions (6 and later). Developers explicitly adopt newer language versions, at which point they will adjust their code for the changes in that new language version, but doing so does not affect Swift code outside of the module that they are working on, because the language version is set on a per-module basis.
Swift language version 6, which we'll refer to herein as Swift 6, offers an opportunity to introduce a targeted set of source-incompatible changes to the language. Swift 6 must not change the fundamental shape of the language, nor make sweeping changes without purpose. Rather, it should only introduce changes that serve a specific goal that benefits the entire Swift ecosystem and is not achievable while maintaining source compatibility. Most features do not fall in this category, so major efforts that are underway in parallel with Swift 6---such as the ownership model or constant evaluation---will continue to be developed independently of Swift 6 unless some specific aspect of them requires source-incompatible changes, akin to the Sendable
part of the Swift Concurrency effort.
Swift 6 focus areas
The Swift Language Workgroup has identified three focus areas where systemic improvements for Swift will depend on source-incompatible changes. Proposals that involve source-incompatible changes for Swift 6 should address one of more of these areas:
-
Data-race safety by default: Data-race safety by default is a significant shift to the model that can only be staged in with a new language version, but it has a large payoff because it makes concurrent programs far easier to write correctly. Swift 6 will need to tighten the semantics around
Sendable
and actor-isolation checking, but may also need additional changes or features to make working in that safety model easier. - Performance predictability: Swift presents an expressive and fairly high-level programming model that abstracts away unnecessary details. However, Swift development can encounter performance "cliffs" where a small change can cause unexpected degradation in the run-time performance of a program (e.g., due to excessive copying of copy-on-write data types) or the performance of Swift tools (e.g., "expression too complex" errors). Swift 6 could consider changes to the default language semantics that improve performance predictability, for example by tuning the rules concerning variable lifetimes, making some features that carry a runtime cost opt-in rather than opt-out, or tuning the type inference rules to enable a better-performing implementation of the type checker.
- Package ecosystem scalability: The long-term health of the Swift language and community depends on having a robust ecosystem of packages. The Swift language and package manager might require adjustments to make it easier to grow the package ecosystem. For example, Swift's module system might be improved to limit the effect of a module's implementation dependencies on its client modules, making modules and packages more resilient to change.
The Language Workgroup will evaluate on a case-by-case basis any additional changes that provide sufficiently high value to the language relative to the cost of source incompatibilities they introduce. For example, Swift 6 may include proposals with source-incompatible changes where they are needed to finish a feature that cannot be completed otherwise, such as the regex literal parsing changes in SE-0354 or the requirement for 'any' on existential types introduced in SE-0335.
Swift 6 will also include bug fixes, where the Swift compiler previously accepted code that it shouldn't have, but the need for source compatibility requires it to continue to accept the incorrect code. For example, implicit references to weak self
being non-optional in some cases is a compiler bug that needs to be addressed, but can only be done so when we are willing to introduce a source incompatibility in Swift 6.
Staging changes for Swift 6
Swift 6 will include a number of changes developed over the course of several years, parts of which will have already been implemented but are not available to developers. Swift 5.8 tools will introduce support for "upcoming" features, which allow source-incompatible Swift 6 changes to be explicitly enabled in a module that is built with Swift language version 4 or 5, on a feature-by-feature basis. This kind of piecemeal adoption of Swift 6 changes is important for several reasons:
- Developers will reap the benefits from these improvements sooner, rather than wait until the Swift 6 language version is available and complete.
- Making these changes available to developers prior to Swift 6 provides more experience, allowing us to tune them further for Swift 6 if necessary.
- Incremental adoption of source-incompatible changes reduces source code churn, making each subsequent change easier and less risky.
It is important to note that upcoming features are not forks of the language. Rather, they are incremental steps along the path to Swift 6 that don't individually affect the overall character or feel of the language.