Warning when assigning a closure to an immutable property on a @MainActor isolated struct from a non isolated initializer

I am surprised by the warning below. Is this a bug that I can expect to be fixed by Swift 6 (rather than that the warning truly becomes an error in Swift 6)?

@MainActor
public struct Foo {
    private let bar: @MainActor ()->Bool
    public nonisolated init(bar: @escaping @MainActor ()->Bool) {
        self.bar = bar // Warning: Main actor-isolated property 'bar' can not be mutated from a non-isolated context; this is an error in Swift 6
    }
}
1 Like

The diagnostic is correct, the message is just misleading (and should be improved). It's because your closure is not Sendable, so the assignment is effectively passing a non-Sendable value from a nonisolated context into the main actor. Marking both function types as @Sendable should resolve the warning.

1 Like

Why aren't MainActor isolated closures automatically Sendable? I think I saw some discussion about this or something similar in some thread, but I might be mixing up concepts.

1 Like

I agree that isolated function types should be @Sendable by default.

@mattie wrote a pitch for this at Implicitly Sendable Closures, and I've incorporated this pitch into a slightly larger set of tweaks to improve the usability of isolated types that I'm slowly working on fleshing out.

In your specific case, isolated function types implying @Sendable would resolve the warning.

6 Likes

Am I correct in believing that the following situation will also be resolved by the "Implicitly Sendable Closures" pitch?

func foo() {
    
    @MainActor
    func bar() { // Concurrently-executed local function 'bar()' must be marked as '@Sendable'; this is an error in Swift 6
        
    }
    
    Task { @MainActor in
        bar()
    }
}

but if I add @Sendable on top of @MainActor I get the following warning:

Main actor-isolated synchronous local function 'bar()' cannot be marked as '@Sendable'; this is an error in Swift 6.