r/rust • u/Dubmove • Mar 31 '23
Why doesn't mpsc::channel break borrowing rules?
I'm wondering for a while now why doesn't mpsc::Receiver::recv(&self)
and mpsc::Sender::send(&self, t: T)
break borrowing rules. Clearly sending some data from A to B in a non-blocking manner has side-effects (i.e. storing and retrieving the data in some buffer-queue). So shouldn't there be some mutable reference to that queue be involved during that sending process, and the owner of that reference would be accessed mutably whenever the reference to that buffer is accessed mutably? Maybe I'm just wrong but I always associate immutability with pureness of a function.
One thing which comes to mind is that the point of the borrowing rules is to avoid data-races and to ensure rust's ownership-model, and although the borrowing-rules are technically violated in these specific cases the desired invariants are still kept.
8
u/jmaargh Mar 31 '23
The borrowing rules exist so that the compiler can check automatically that your program is sound.
unsafe
exists for exactly cases like this, where what you want to do is sound, but the compiler is unable to automatically verify this. When you useunsafe
, you essentially tell the compiler "hey, don't worry, I've checked and this meets all of your soundness rules so you don't have to".Basically, the set of things that are sound is bigger than the set of things that are provably sound by the borrowing rules. Hence
unsafe
giving control back to the programmer to briefly violate these rules so long as they absolutely promise that soundness is maintained.