Source Compatibility

Lay-contributor's answer, not official policy here.

There are two kinds of Swift releases:

  • "Non-breaking release": Language changes that would break any existing Swift code are not permitted. Any code that was valid before should continue to build and function the same way.

  • "Source-breaking release": Some language changes may affect existing, valid code, either making it invalid or changing its behavior. A source-breaking release will add a new version to the compiler's -swift-version flag; specifying the previous version will cause it to emulate the old compiler's behavior in situations where it's changed, and usually emit deprecation warnings telling the user what to update for the new version.*

However, things are not quite as black-and-white as this. A non-source-breaking release may sometimes include very small changes—bug fixes, new overloads—that could theoretically break existing code, as long as we believe the breakage will be very small or nonexistent in practice and the benefit is worth the risk. This is very much a judgement call and the core team is typically involved with these decisions.

Contrariwise, a source-breaking release is not a free-for-all—even in those versions, we require a strong motivation to break source compatibility. Generally, the existing behavior must be "actively harmful"—you must be able to point to specific problems it causes and demonstrate that they can only be solved by breaking source compatibility. Mere preference is not enough.

When source stability comes up in evolution discussions, people are usually saying one of two things:

  1. This proposal cannot be accepted for the next release, because the next release is non-source-breaking. It will have to wait until a future source-breaking release, and the implementation will need to continue emulating the old behavior in old language versions.

  2. This proposal cannot be accepted even in a source-breaking release, because the existing behavior is not actively harmful. Unless there is some sort of major overhaul of the language where we decide to accept "just because" changes—which doesn't seem likely—there is no future version where we will accept this change.

Which one they mean depends on the context.

So in short, other than ABI-breaking changes, and leaving aside the need to have a Swift 5 mode which emulates the old behavior, there are no decisions we are completely stuck with if the problem is bad enough. But we have to balance the badness of breaking source compatibility against the badness of the problem at hand, and we value source compatibility pretty highly.

Hope this helps!


* We have retired -swift-versions in the past, but we don't ever plan to retire -swift-version 5 because it is used in swiftinterface files, which we've promised future compilers will continue to support. I don't know whether or when we could retire -swift-version 4 and -swift-version 4.2.

11 Likes