Enable data-race safety checking
Use Swift 6 to get full data-race safety checking or add checking to an existing Swift 5 project.
Enable the Swift 6 language mode
To enable data race safety checking for a Swift project, use the Swift 6 language mode. By default, Swift 6 enables full data race safety checking.
Enable the Swift 6 language mode
Swift 6 mode with Swift packages
A Package.swift file that uses swift-tools-version of 6.0 enables the Swift 6 language mode for all targets. You can still set the language mode for the package as a whole using the swiftLanguageModes property of Package. You can also change the language mode as needed on a per-target basis using the new swiftLanguageMode build setting:
// swift-tools-version: 6.0
let package = Package(
name: "MyPackage",
products: [
// ...
],
targets: [
// Uses the default tools language mode (6)
.target(
name: "FullyMigrated",
),
// Still requires 5
.target(
name: "NotQuiteReadyYet",
swiftSettings: [
.swiftLanguageMode(.v5)
]
)
]
)Note that if your package needs to continue supporting earlier Swift toolchain versions and you want to use per-target swiftLanguageMode, you will need to create a version-specific manifest for pre-6 toolchains. For example, if you’d like to continue supporting 5.9 toolchains and up, you could have one manifest Package@swift-5.9.swift:
// swift-tools-version: 5.9
let package = Package(
name: "MyPackage",
products: [
// ...
],
targets: [
.target(
name: "FullyMigrated",
),
.target(
name: "NotQuiteReadyYet",
)
]
)And another Package.swift for Swift toolchains 6.0+:
// swift-tools-version: 6.0
let package = Package(
name: "MyPackage",
products: [
// ...
],
targets: [
// Uses the default tools language mode (6)
.target(
name: "FullyMigrated",
),
// Still requires 5
.target(
name: "NotQuiteReadyYet",
swiftSettings: [
.swiftLanguageMode(.v5)
]
)
]
)If instead you would just like to use Swift 6 language mode when it’s available (while still continuing to support older modes) you can keep a single Package.swift and specify the version in a compatible manner:
// swift-tools-version: 5.9
let package = Package(
name: "MyPackage",
products: [
// ...
],
targets: [
.target(
name: "FullyMigrated",
),
],
// `swiftLanguageVersions` and `.version("6")` to support pre 6.0 swift-tools-version.
swiftLanguageVersions: [.version("6"), .v5]
)Swift 6 mode with command-line invocations
-swift-version 6 can be passed in a Swift package manager command-line invocation using the -Xswiftc flag:
~ swift build -Xswiftc -swift-version -Xswiftc 6
~ swift test -Xswiftc -swift-version -Xswiftc 6To enable the Swift 6 language mode when running swift or swiftc directly at the command line, pass -swift-version 6:
~ swift -swift-version 6 main.swiftSwift 6 mode with Xcode
You can control the language mode for an Xcode project or target by setting the “Swift Language Version” build setting to “6”.
Setting XCConfig
You can also set the SWIFT_VERSION setting to 6 in an xcconfig file:
// In a Settings.xcconfig
SWIFT_VERSION = 6;Enable data-race safety checking as warnings
With a Swift target or package in a Swift 5 language mode or earlier, you can address data-race safety issues in your projects on a module-by-module basis. Enable the compiler’s actor isolation and Sendable checking as warnings to assess your progress toward eliminating data races before turning on the Swift 6 language mode.
Complete data-race safety checking can be enabled as warnings using the -strict-concurrency compiler flag.
Checking with Swift packages
To enable complete concurrency checking for a target in a Swift package using Swift 5.9 or Swift 5.10 tools, use SwiftSetting.enableExperimentalFeature in the Swift settings for the given target:
.target(
name: "MyTarget",
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")
]
)When using Swift 6.0 tools or later, use SwiftSetting.enableUpcomingFeature in the Swift settings for a pre-Swift 6 language mode target:
.target(
name: "MyTarget",
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency")
]
)Targets that adopt the Swift 6 language mode have complete checking enabled unconditionally and do not require any settings changes.
Checking with command-line invocations
To enable complete concurrency checking when running swift or swiftc directly at the command line, pass -strict-concurrency=complete:
~ swift -strict-concurrency=complete main.swift-strict-concurrency=complete can be passed in a Swift package manager command-line invocation using the -Xswiftc flag:
~ swift build -Xswiftc -strict-concurrency=complete
~ swift test -Xswiftc -strict-concurrency=completeThis can be useful to gauge the amount of concurrency warnings before adding the flag permanently in the package manifest as described in the following section.
Checking with Xcode
To enable complete concurrency checking in an Xcode project, set the “Strict Concurrency Checking” setting to “Complete” in the Xcode build settings.
Setting XCConfig
Alternatively, you can set SWIFT_STRICT_CONCURRENCY to complete in an xcconfig file:
// In a Settings.xcconfig
SWIFT_STRICT_CONCURRENCY = complete;