-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Open
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwareBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labelsThis issue needs more specific labels
Description
Description
- Simple main.swift (this is important) app with
swift-tools-version: 6.0
package - Having a old target without any Sendable mark yet with
.swiftLanguageMode(.v5)
enabled - Running at top level in main.swift file
App will run but crash when trying to execute this closure with an error Task 1: EXC_BREAKPOINT (code=1, subcode=0x1004cbbc4)
Reproduction
Package.swift
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "App",
platforms: [.macOS(.v15)],
targets: [
.target(
name: "System",
swiftSettings: [.swiftLanguageMode(.v5)]
),
.executableTarget(
name: "App",
dependencies: [ "System" ]
),
]
)
System/System.file
public class System {
public struct Settings { public var name: String = "" }
public let settings: Settings
public convenience init(configureWith configure: (inout Settings) -> () = { _ in () }) async {
var settings = Settings()
configure(&settings) // runtime crash here with `Task 1: EXC_BREAKPOINT (code=1, subcode=0x1004cbbc4)`
self.init(settings: settings)
}
public init(settings: Settings) {
self.settings = settings
}
public func run() async throws {
try await Task.sleep(for: .seconds(3))
}
}
App/main.swift
import System
let system = await System {
$0.name = "Demo"
}
print(system.settings.name)
try await system.run()
print("Done")
Stack dump
thread #1, queue = 'com.apple.main-thread'
frame #0: 0x000000018f8b1c34 libsystem_kernel.dylib`mach_msg2_trap + 8
frame #1: 0x000000018f8c4028 libsystem_kernel.dylib`mach_msg2_internal + 76
frame #2: 0x000000018f8ba98c libsystem_kernel.dylib`mach_msg_overwrite + 484
frame #3: 0x000000018f8b1fb4 libsystem_kernel.dylib`mach_msg + 24
frame #4: 0x000000018f993c80 CoreFoundation`__CFRunLoopServiceMachPort + 160
frame #5: 0x000000018f9925d8 CoreFoundation`__CFRunLoopRun + 1188
frame #6: 0x000000018fa50898 CoreFoundation`_CFRunLoopRunSpecificWithOptions + 532
frame #7: 0x000000018f9e9a44 CoreFoundation`CFRunLoopRun + 64
frame #8: 0x0000000287fd7ee8 libswift_Concurrency.dylib`CFMainExecutor.run() + 48
frame #9: 0x0000000287fd7ba0 libswift_Concurrency.dylib`protocol witness for RunLoopExecutor.run() in conformance DispatchMainExecutor + 48
frame #10: 0x0000000287fd7f94 libswift_Concurrency.dylib`swift_task_asyncMainDrainQueueImpl + 108
frame #11: 0x0000000287ff8170 libswift_Concurrency.dylib`swift_task_asyncMainDrainQueue + 92
frame #12: 0x0000000100000c34 App`main at main.swift:0
frame #13: 0x000000018f535d54 dyld`start + 7184
* thread #3, name = 'Task 1', queue = 'com.apple.root.default-qos.cooperative', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1004cbbc4)
frame #0: 0x00000001004cbbc4 libdispatch.dylib`_dispatch_assert_queue_fail + 120
frame #1: 0x0000000100506d30 libdispatch.dylib`dispatch_assert_queue$V2.cold.1 + 116
frame #2: 0x00000001004cbb48 libdispatch.dylib`dispatch_assert_queue + 108
frame #3: 0x0000000287f900a4 libswift_Concurrency.dylib`_swift_task_checkIsolatedSwift + 48
frame #4: 0x0000000287ff0df4 libswift_Concurrency.dylib`swift_task_isCurrentExecutorWithFlagsImpl(swift::SerialExecutorRef, swift::swift_task_is_current_executor_flag) + 356
frame #5: 0x0000000100001344 App`closure #1($0=(name = "")) -> () in App at main.swift:0
* frame #6: 0x00000001000016e0 App`System.__allocating_init(configure=0x00000001000012f0 App`closure #1 (inout System.System.Settings) -> () in App at main.swift:3) at System.swift:9:5
frame #7: 0x0000000100000cec App`async_MainTQ0_ at main.swift:3:20
Expected behavior
If you change main.swift to App.swift file, like:
import System
@main
struct App {
static func main() async throws {
let system = await System { // Sending value of non-Sendable type '(inout System.Settings) -> ()' risks causing data races
$0.name = "Demo"
}
print(system.settings.name)
try await system.run()
print("Done")
}
}
Compiler will fire an error Sending value of non-Sendable type '(inout System.Settings) -> ()' risks causing data races
.
Guess should be same when compiled at top level in main.swift.
Environment
macOS 26, Xcode 26.0.1, Swift 6.2 (6.2.0.19.9)
Additional information
I know this an edge case which can be fixed by marking closure as sending or Sendable, just sometimes you don't have this option with 3rd party frameworks.
bilousoleksandr
Metadata
Metadata
Assignees
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwareBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labelsThis issue needs more specific labels