Implicitly Sendable Closures

According to SE-0316:

A non-protocol type that is annotated with a global actor implicitly conforms to Sendable .

However, this actually isn't true for closures today.

@MainActor
class MyClass {
	func doThing() {
	}
}

func test() {
	let closure: @MainActor () -> Void = {
		print("hmmmm")
	}

	let value = MyClass()

	Task {
		// warning about capturing non-Sendable
		await closure()

		// this is fine
		await value.doThing()
	}
}

A solution is to mark closure as both @MainActor and also @Sendable. But, that shouldn't be necessary - this closure should be implicitly Sendable. Besides making the semantics consistent, this is a significant improvement in usability.

This was brought up in this thread Should global-actor-isolated functions be implicitly Sendable? - #2 by mattie. While the original problem posted does now work without warnings, the closure example above is still problematic.

Thank you so much @Jumhyn for bringing this up originally and to @hborla for explaining. Official proposal forthcoming!

8 Likes

Here is a link to a draft proposal:

1 Like