Would those be breaking changes? If not, they could be in Swift 6 but would not be relevant to this thread about the Swift 6 language mode.
It looks like #3 that you linked is related to SE-0384 that's currently in review, so please make sure to offer any input you have there as well.
I don't have enough swift compiler knowledge to estimate if those would be a breaking changes or not, but to my judging, if according to this comment the proper way of supporting ObjC forward declarations is to have an index of ObjC type names in Swift, it may affect the swift module format. Deterministic builds support, if it involves changing the way how and/or where the include paths are stored, might affect the swift module format as well. Parallelization of module loading by lldb might require the change of the module format, too. So it would be great if these issues can be carefully considered and taken into account in terms of
- what is the vision for the solution to them, and
- should the solution be prioritized and implemented as a part of the Swift 6 scope.
I suspect I'm not alone in that I'm not entirely sure what a "language mode" is.
This is explained in the post itself at length. Indeed, thatâs kind of the central point of the post.
I was going to quote some relevant parts of it here but it would end up being just cutting and pasting entire paragraphs, so instead please refer to them above.
The briefest relevant snippet, I suppose, would be that the Swift 6 language mode is:
a targeted set of source-incompatible changes to the language. . . . Most features do not fall in this category, [including] major efforts that are underway . . . such as the ownership model or constant evaluation
Itâs unclear whether or not the features @edudnyk has described, which seem to have an underlying theme of âbuild system extensibilityâ, would need to be confined to a new language mode. Doesnât that make it in-bounds for this thread?
The original post certainly has lots of details. I just feel like the concept of what a language mode actually is gets lost. Is it a compiler setting? Or a more abstract concept?
Itâs a compiler setting. It already exists today; thatâs how the compiler decides whether to make sendability issues warnings (Swift 5.6 language mode) or errors (5.7 language mode).
That's what I suspected, but I wasn't totally sure. Thanks.
One thing I'd love to see addressed in Swift 6 is C-interop, particularly concerning pointers to forward-declared structs, known in Swift only as OpaquePointer
.
Losing all the type info for C APIs that use this pattern (which are, in my limited experience, rather common) makes working with them rather annoying.
This blog post describes the situation in more detail.
The blog post also says changing this would be both API- and ABI-breaking, so I'm not sure this is actually addressable even in a new language mode, but I thought I'd bring it up in case folks agree this is worth the API break and we can find some way to avoid breaking ABI.
Might the ongoing C++ integration work benefit this?
That's certainly something that would require a new language mode, and as you note we'd have to navigate the ABI challenges as well as the source incompatibility. That said, I think this is something that could be considered for Swift 6.
Doug
This isn't quite accurate. The compiler setting (SWIFT_VERSION
or Swift Language Version in Xcode, -swift-version
to the compiler) only supports 4, 4.2, and 5 at this time. Things like the changes you mention (sendability warnings) are gated by compiler version (you get the new warnings using the new compiler), not the compiler's Swift version setting. IIRC, the Swift 6 compiler will move to supporting 5 (or perhaps a later version like 5.8) and 6 as language "modes", with all of the new behavior enabled under the 6 mode.
For sendability errors, the level of checking is controlled by the SWIFT_STRICT_CONCURRENCY
setting (or whatever the command line equivalent is) as well as other compiler flags. And like I said, it also changes between compiler versions as the rules are refined.
@Jon_Shier, there is no need to speculate or recall from memory: the original post spells out the correct answer about Sendable
checking and future language mode support explicitlyâ
Iâm the one who incorrectly recalled from memory.
Looking at what you quoted, I'm not sure it's clear. It would be good to clarify how language versions work and exactly what the implications for sendability checking really are. I'll try to clarify here.
Language Version Support
The Swift compiler supports building using a specific language version (aka language mode), which facilitates compatibility with older language releases. Currently (Swift 5.7), the supported language versions are 4, 4.2, and 5. These versions are not equivalent to building using an older version of the compiler but should be backward compatible (they are not forward compatible as the newer compiler allows things, even when building for an older version, that the older version does not support).
You can pass a version to the compiler using the -swift-version
flag (-swift-version 5
) or by setting the "Swift Language Version" (SWIFT_VERSION
) setting in Xcode.
When Swift 6 is released, the available versions will be 4, 5, and 6.
Open question: what will be the difference between the current 4 and 4.2 versions and the Swift 6 version 4 support? Is that support even necessary anymore?
Sendability Checking and Language Versions
This is a little more unclear. Currently, there are various flags in the Swift 5.5 and later compilers to allow control over various aspects of the compiler's concurrency safety checking. In 5.6 and later compiler versions, the -strict-concurrency
option ("Strict Concurrency Checking" or SWIFT_STRICT_CONCURRENCY
in Xcode) can be used to enable more compiler checking of concurrency safety with minimal
, targeted
, and complete
settings (-strict-concurrency=minimal
), with minimal
the default. In Swift 6, the equivalent of complete
will become the default. There are also other compiler settings which control concurrency features but it's unclear how those settings will be affected in Swift 6.
Confusingly, the OP states:
Presumably this doesn't actually mean "disabled" as in "turned off", as that would be a regression from the current compiler. Instead, it seems like it should mean the default falls back to minimal
rather than complete
, with the option to reenable complete
checking even when building in version 5. But this definitely needs to be clarified.
I've gone back and added "4.2" to the list in the original post, because it is a supported language version. The differences between 4 and 4.2 are quite minor.
Whether Swift 4 and 4.2 will be supported in future compiler versions is up to the maintainers of the Swift compiler, and should be decided based on data about how prevalent Swift 4/4.2 code are in the ecosystem and weighed against the benefits of having fewer language modes to support. From a technical standpoint, very little changed from Swift 4 -> 4.2 -> 5, and 6 would be the first real jump since the tumultuous days before Swift 4.
It means that'll be downgraded to warnings or suppressed entirely; I've updated the post to try to clarify that.
Doug

Data-race safety by default
I've noticed previously that -enable-actor-data-race-checks
is very blunt - it appears to add a preamble to literally every actor-isolated partial function, even when actor isolation should be able to be proven statically.
Will the implementation be improved to limit runtime checks, or is the plan to enable it as it currently is?
Example. Calling one @MainActor
function from another @MainActor
function:
@MainActor
func funcOne() async -> Int {
funcTwo()
}
@MainActor
func funcTwo() -> Int {
return 42
}
// Compiling with -O (no data race checks)
(1) suspend resume partial function for output.funcOne() async -> Swift.Int:
push rax
mov rdi, qword ptr [r14 + 16]
call swift_release@PLT
mov rax, qword ptr [r14 + 8]
mov edi, 42 ; <-- The result
pop rcx
jmp rax
// Compiling with -O -enable-actor-data-race-checks
(1) suspend resume partial function for output.funcOne() async -> Swift.Int:
push r15
push rbx
push rax
mov rbx, qword ptr [r14 + 16]
mov r15, qword ptr [r14 + 32]
mov r13, rbx
call ($sScM6sharedScMvgZ)@PLT ; static Swift.MainActor.shared.getter
mov r13, rax
mov rdi, rbx
mov rsi, r15
call ($sScA15unownedExecutorScevgTj)@PLT ; dispatch thunk of Swift.Actor.unownedExecutor.getter
mov rbx, rax
mov r15, rdx
mov rdi, rax
mov rsi, rdx
call swift_task_isCurrentExecutor@PLT ; runtime call
test al, 1
jne .LBB2_2
lea rdi, [rip + ".L.str.20.output/example.swift"]
mov esi, 20
mov ecx, 7
mov edx, 1
mov r8, rbx
mov r9, r15
call swift_task_reportUnexpectedExecutor@PLT
.LBB2_2:
mov rbx, qword ptr [r14 + 24]
mov rdi, r13
call swift_release@PLT
mov rdi, rbx
call swift_release@PLT
mov rax, qword ptr [r14 + 8]
mov edi, 42 ; <-- The result
add rsp, 8
pop rbx
pop r15
jmp rax

Package ecosystem scalability
I'd like to mention one thing that would help us develop a package ecosystem that is more robust: non-exhaustive enums. Even if just an option.
We also have a problem with packages that use non-standard language features (e.g. @_exported import
, _modify
, @inline(__always)
). I hope that is also on the list of things to address when it comes to the long-term health of the package ecosystem.
Oh and one more thing: the Unicode organisation is preparing a new technical standard, describing best practices for handling Unicode in source code. If we're going to be making breaking changes with Swift 6, it may also be worth considering whether we should make any changes in light of these recommendations.
Some of the changes may have an impact on parsing (which may be different to how Swift currently parses source code and hence be a breaking change), allowed identifiers, etc.
The current draft is here: