Inout sending value passing into inout sending closure

Mutex is a great tool But I want to wrap it in a reference type. So, I can pass around. but I encounter some errors:

public final class Protect<T: ~Copyable>: @unchecked Sendable {

    let mutex: Mutex<T>

    init(_ storedValue: consuming sending T) {
        self.mutex = Mutex(storedValue)
    }

    func safe<R: ~Copyable, E>(
        _ execute: (inout sending T) throws(E) -> sending R
    ) throws(E) -> sending R {
/*
Returning a task-isolated '@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@sil_sending @inout τ_0_0) -> (@sil_sending @out τ_0_2, @error_indirect τ_0_1) for <T, E, R>' value as a 'sending' result risks causing data racesSourceKit
main.swift(60, 19): Returning a task-isolated '@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@sil_sending @inout τ_0_0) -> (@sil_sending @out τ_0_2, @error_indirect τ_0_1) for <T, E, R>' value risks causing races since the caller assumes the value can be safely sent to other isolation domains
main.swift(60, 19): '@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@sil_sending @inout τ_0_0) -> (@sil_sending @out τ_0_2, @error_indirect τ_0_1) for <T, E, R>' is a non-Sendable type
*/
        try mutex.withLock { (storedValue: inout sending T) throws(E) -> sending R in
/*
Sending 'storedValue' risks causing data racesSourceKit
main.swift(61, 17): 'storedValue' used after being passed as a 'sending' parameter; Later uses could race
main.swift(61, 37): 'inout sending' parameter must be reinitialized before function exit with a non-actor isolated value
main.swift(62, 9): 'inout sending' parameter must be reinitialized before function exit with a non-actor isolated value
*/
            try execute(&storedValue)
        }
    }
}

Swift version 6.0.1 (swift-6.0.1-RELEASE) Target: aarch64-unknown-linux-gnu

is it a bug? or did I do anything wrong?

A recent thread with similar material, though I think it only addresses this as "probably a bug": Sending, inout sending, Mutex

Have you tried

try mutex.withLock(execute)

Tried that and got the error: Returning task-isolated 'execute' as a 'sending' result risks causing data races

import Synchronization

public final class Protect<T: ~Copyable>: @unchecked Sendable {
    let mutex: Mutex<T>

    init(_ storedValue: consuming sending T) {
        self.mutex = Mutex(storedValue)
    }

    func safe<R: ~Copyable, E>(
        _ execute: (inout sending T) throws(E) -> sending R
    ) throws(E) -> sending R {
        try mutex.withLock (execute) // Error: Returning task-isolated 'execute' as a 'sending' result risks causing data races
    }
}

I don't understand, but making the execute param sending gets rid of the error.

import Synchronization

public final class Protect<T: ~Copyable>: @unchecked Sendable {

    let mutex: Mutex<T>

    init(_ storedValue: consuming sending T) {
        self.mutex = Mutex(storedValue)
    }

    func safe<R: ~Copyable, E>(
        _ execute: sending (inout sending T) throws(E) -> sending R
    ) throws(E) -> sending R {
        try mutex.withLock (execute)
    }
}

I actually also found out adding “sending” to write like that.

Seems like bugs