public final class Protect<T: ~Copyable>: @unchecked Sendable {
@usableFromInline
let locker: NSLock = NSLock()
@usableFromInline
var storedValue: T
@inlinable
public init(_ storedValue: consuming sending T) {
self.storedValue = storedValue
}
@discardableResult
@inlinable
public func safe<R: ~Copyable, E>(
_ execute: (inout sending T) throws(E) -> sending R
) throws(E) -> sending R {
locker.lock()
defer {
locker.unlock()
}
return try execute(&storedValue)
}
}
Now, I try to return the noncopyable type from a closure inside the wrapper:
struct NonCoypableBox<T: ~Copyable>: ~Copyable {
var value: T
init(_ value: consuming T) {
self.value = value
}
}
func foo() {
let protectedValue: Protect<NonCoypableBox<Int>?> = Protect(NonCoypableBox(42))
// Referencing instance method 'safe' on 'Optional' requires that 'NonCoypableBox<Int>' conform to 'Copyable'
let value = protectedValue.safe { value in
let v = value.take()
value = nil
return v
}
}
If i move Protect type into the same package. i won't get this error.
Am I missing something here?
I think it is a bug.
I see a different error when I try to compile your code:
use.swift:16:23: error: value of type 'NonCoypableBox<Int>?' has no member 'take'
14 | // Referencing instance method 'safe' on 'Optional' requires that 'NonCoypableBox<Int>' conform to 'Copyable'
15 | let value = protectedValue.safe { value in
16 | let v = value.take()
| `- error: value of type 'NonCoypableBox<Int>?' has no member 'take'
17 | value = nil
18 | return v
I can't reproduce this with either a nightly swift or 6.0.3 which ships along with Xcode 16.2 and is available as a snapshot. Is it perhaps the case that the diagnostic is stale? It makes reference to a method on Optional, but safe is being invoked on a value of type Protect<NonCopyableBox<Int>?>
Yup. I put your Protect type into a package and added that package as a dependency for an app target. I also tried to create a test target within the package's domain to see if that might reproduce it and was similarly unable to get this diagnostic to appear.