One of the Stage 1 goals of Swift 4 is source compatibility with Swift 3, but what does that precisely mean and how will we determine if the goal is achieved? This is the current proposal of how this goal ties back to the Swift 3.x and Swift 4 releases. Is there anything else that’s missing or should be discussed?
The source compatibility goal for Swift 4 means that sources that previously compiled with the Swift 3 compiler will continue to compile with no source modifications with the Swift 3.x and Swift 4 compilers.
Swift 3.x releases have the goal of source compatibility with Swift 3. This is the default mode and there is no compatibility flag.
This means that Swift 3 code should be able to build with the Swift 3.x compiler without modification as much as practically possible. The same applies to SwiftPM packages with Swift 3 source code.
Swift 3.x code will not necessarily compile with the Swift 3 compiler. For example, new language features could be added.
The Swift 4 compiler will include a language compatibility flag -swift-version that accepts 3 or 4 as arguments and controls the compatibility mode (SR- 2582 <https://bugs.swift.org/browse/SR-2582>).
The -swift-version 3 compatibility mode has the goal of source compatibility as much as practically possible with Swift 3.x (including 3, 3.0.x, 3.x).
The -swift-version 4 compatibility allows approved source code breakages from Swift 3.x (including 3, 3.0.x, 3.x). Proposed source breaking changes should be discussed on swift-evolution and highlighted in evolution proposals.
All the sources in a module (e.g, SwiftPM packages, targets in Xcode) will be built in the same compatibility mode, but modules built with different compatibility modes can be linked into a single binary and will interoperate.
Thus a module can be migrated from Swift 3 to 3.x to 4 independently of its dependencies.
The Swift Package Manager will allow package authors to specify a list of compatibility modes.
The Swift compiler already provides a mechanism for conditional compilation based on the compiler version with the #if swift syntax. SE-0020 <https://github.com/apple/swift-evolution/blob/master/proposals/0020-if-swift-version.md>. Swift 4 will also provide mechanisms to conditionalize code based on the compatibility version.
The @available(...) attribute has been expanded to support the swift language version with SE-0141 <https://github.com/apple/swift-evolution/blob/master/proposals/0141-available-by-swift-version.md>. For example, @available(swift 3).
Maintaining source compatibility with Swift 3 in practice while continuing development is not always clear-cut. It often comes down to tradeoffs. Let’s review a few cases.
New features may become available if they do not take up syntactic space that might be commonly used by existing Swift code.
If a bug fix breaks source in a fringe case as determined by a scan of existing source, the benefit might outweigh the cost and it could be allowed.
Changes to existing APIs have high bar to clear as they should provide a significant benefit to clients and have minimal impact on existing, real-life code. These changes should be considered for inclusion in the -swift-version 4 compatibility mode of the Swift 4 compiler instead.
New warnings are allowed because they do not require source code changes.
To summarize, any proposed source breakage from Swift 3 for the Swift 3.x compilers or the -swift-version 3 compatibility mode of the Swift 4 compiler, should be small in scope of code affected and weighed against the goals of source compatibility described above. It should be approved on swift-evolution.
For Apple Platforms, source compatibility can also be affected by changes to the Apple SDKs. Last year, Swift 2.3 required a migration from Swift 2.2 to account for changes in the SDKs even though no language changes were introduced. This year, source compatibility is defined more strictly to require that the Apple SDKs only add source compatible changes when used with the Swift 3.x compilers or when used with the Swift 3 compatibility mode (-swift-version 3) in the Swift 4 compiler. The ‘API notes’ feature has been augmented and can now express how an API is imported for a specific Swift version. This feature allows the view of the evolved Apple SDKs to stay the same as with Swift 3 when Swift 3 source compatibility is expected.