Skip to content

Incorrect actor isolation assumption across Swift 5/6 module boundary leads to dispatch_assert_queue crashes #75453

Open
@NachoSoto

Description

@NachoSoto

Reproduction

Consider the following code, split in 2 modules:

// Module 1, compiled with Swift 5 and no strict concurrency checking:
public class A {
  public init() {}

  public func f(_ value: @escaping () -> Void) {
    DispatchQueue.global().async { value() }
  }
}

// Module 2, compiled with Swift 6:
import Module1

@MainActor
func g() {
  A().f {
    // This is assumed to be @MainActor isolated by default, leading to `dispatch_assert_queue` failed assertion
  }
}

Expected behavior

The code compiles with no warnings (because the closure passed to f is valid based on the definition), but it crashes at runtime due to it being inferred as @MainActor, and executing outside of it.

The closure shouldn't become @MainActor isolated implicitly just because it's called from a @MainActor method.

Environment

swift-driver version: 1.112.3 Apple Swift version 6.0 (swiftlang-6.0.0.6.8 clang-1600.0.23.1)
Target: arm64-apple-macosx14.0

Additional information

No response

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.concurrencyFeature: umbrella label for concurrency language features

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions