Skip to content

Mutex allows to return the protected Value instance without reinitialization #81274

Open
@NSFatalError

Description

@NSFatalError

Description

From the Mutex proposal, following code is unsafe and it's correctly diagnosed:

import Synchronization

open class NonSendable {}

final class Store: Sendable {
    private let lock = Mutex(NonSendable())

    func referenceCurrentState() -> NonSendable {
        var reference: NonSendable!
        lock.withLock { state in
           reference = state
           // Expected error: 'inout sending' parameter 'state' cannot be task-isolated at end of function
        }
        return reference
    }
}

The same diagnostic however isn't applied when we simply return the protected state from the closure passed to withLock method (see reproduction).

Reproduction

import Synchronization

open class NonSendable {
    func mutate() { ... }
}

final class Store: Sendable {
    private let lock = Mutex(NonSendable())

    func returnCurrentState() -> NonSendable {
        lock.withLock { state in
            return state 
            // No error!
        }
    }
}

let store = Store()
await withTaskGroup { group in
    for _ in 0 ..< 1000 {
        group.addTask {
            store.returnCurrentState().mutate()
        }
    }
}

Expected behavior

Returning inout sending value should require reinitialization.

Environment

Apple Swift version 6.1 (swift-6.1-RELEASE)
Target: arm64-apple-macosx15.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