Hi,
I’m continueing my experiments with noncopyable types and ownership in Swift and ran into what looks a bit surprising to me:
protocol BulkChanges: ~Escapable, Sendable {
func append(_ integer: Int)
}
protocol ShardData: ~Copyable, Sendable {
associatedtype T: BulkChanges
borrowing func withBulkChanges<R>(
_ body: (borrowing Self.T) throws -> R
) rethrows -> R
}
protocol API {
func makeP2() -> any (ShardData & ~Copyable)
}
struct Shard: ~Copyable {
let shardData: any (ShardData & ~Copyable)
mutating func run() {
self.shardData.withBulkChanges { bulkChanges in
bulkChanges.append(42)
}
// ❌ error: Missing reinitialization of inout parameter 'self' after consume
}
}
That seems that I specified correctly that withBulkChanges is borrowing shardData and closure should not capture self.
Interestingly, the following workaround compiles:
extension Shard {
borrowing func withShardData<R>(
_ body: (borrowing any (ShardData & ~Copyable)) throws -> R
) rethrows -> R {
try body(self.shardData)
}
mutating func run() {
self.withShardData { shardData in
shardData.withBulkChanges { bulkChanges in
bulkChanges.append(43)
}
}
}
}
I wonder if I do smth wrong or should I consider it as a compiler bug in one of the cases?