withUnsafeMutableBytes(_:)
is a mutating
method on Data
, therefore it requires write access to data
for the duration of the call. By accessing data.count
in the closure, you're starting a new read on data
which conflicts with the current write access.
Even though in your particular case I don't believe there shouldn't be any problems with this code, as the mutation doesn't mutate the count
; the exclusivity checking logic is conservative and assumes that any mutating
method might mutate any part of the value it's called on, and therefore forbids the overlap.
You can solve the problem by first binding the count to a temporary:
func foo() {
var data = Data(count: 16)
let count = data.count
data.withUnsafeMutableBytes { ptr in
ptr[0] = UInt8(count)
}
print(data)
}
Now the read access for data.count
happens before the write access for withUnsafeMutableBytes
, so there's no conflict.
The fact that the diagnostic is a warning rather than an error appears to be due to a fix for a false negative where the compiler wouldn't look through reabstraction thunks (such as are required for generic functions to ensure the calling convention is passing generic values indirectly). This will become an error though (and is in the latest snapshots).