The first answer is effectively correct, but if you want something more technical, remember that mutating
is equivalent to inout
on self
, and inout
is formally “copy-in, copy-out”. So the Law of Exclusivity says that f
is being accessed for the entire duration of the call to modifyX
. But within modifyX
, self
is an independent value that was initialized from f
. Then that value is accessed for the duration of the call to modifyY
, being copied in to another self
.
The way you get an exclusivity violation on one thread is by referring back to the original storage, which can only happen if it’s a global or if there’s a reference type involved (class or closure).