Hi there, I'm experimenting with noncopyable types in Swift and encountered a problem when trying to consume a value within a closure. Here's a minimal reproduction:
struct Foo: ~Copyable {
}
func withBlock(_ block: () -> Void) {
block()
}
func playground() async throws {
let foo = Foo() // Noncopyable 'foo' cannot be consumed when captured by an escaping closure
withBlock {
consume foo
}
}
It seems like Swift does not support moving capture. Is this a known limitation of the current implementation of closure (e.g., no FnOnce like Rust)?
I can think of an inconvenient workaround to explicitly consume the value in function parameters:
func withComsumingBlock<T: ~Copyable>(
_ t: consuming T,
block: (consuming T) -> Void
) {
block(t)
}
func playground() async throws {
let foo = Foo()
withComsumingBlock(foo) { foo in
consume foo
}
}
This pattern changes the callee API, and I need to write boilerplate extensions for external libraries. Is there any better workaround in Swift 6.2+ or future SE for this? Thanks!