Overlapping access warning in withUnsafeMutableBytes

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).

3 Likes