`-strict-concurrency=complete` relaxes concurrency check

Compiler complains about concurrency for this code

class NonSendableClass {
    var data: String
    init(data: String) {
        self.data = data
    }
}

@available(*, unavailable)
extension NonSendableClass: Sendable { }

func Foo(_ obj: NonSendableClass) async -> Int{
  obj.data = "Swift"
  return 0
}

actor SomeActor{
  func main() async {
    let nonSendableObject = NonSendableClass(data: "Hello, Swift!")
    // Passing argument of non-sendable type 'NonSendableClass' outside of actor-isolated context may introduce data races; this is an error in the Swift 6 language mode
    let _ = await Foo(nonSendableObject)
  }
}

This is reasonable (can't pass non-sendable objects across actor boundaries), but when I enable -strict-concurrency=complete this warning disappeared. Isn't -strict-concurrency=complete the most strict level which enforces concurrency check for everything?

My Package.swift:

// swift-tools-version: 5.9.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
import CompilerPluginSupport

let package = Package(
    name: "Untitled",
    platforms: [
      .macOS(.v14)
    ],
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
      .executableTarget(
          name: "Untitled",
          swiftSettings: [
               // If I comment this line the warning shows up, otherwise there's no warning
              .unsafeFlags(["-Xfrontend", "-strict-concurrency=complete"])
          ]
        )
    ],
    swiftLanguageVersions: [.v5]
)

Using Xcode 16.1 beta

1 Like

Try using

.enableExperimentalFeature("StrictConcurrency")

instead of the unsafeFlag.

1 Like

Yeah this works. May I ask what's the difference between these two settings? Why unsafeFlags doesn't work but enableExperimentalFeature does?

1 Like

With region based isolation it actually should be fine and I think with Swift 6 you won’t get warning in this example — nonSendable in a disconnected region here and can be passed if won’t be used after.

1 Like

Yeah you're right, after I switch to swiftLanguageModes: [.v6] the warning no longer shows up, thanks!

2 Likes