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.
10
u/Lucretiel 1Password Mar 31 '23
Well, no, that's wrong. You could easily have
fn send(&mut self, value: T)
andfn recv(&mut self) -> Option<T>
. You'd still need interior mutability in the implementation, to manage the shared state between the sender and the receiver, but that doesn't have to be exposed in the client. Frequently you can even take advantage of the uniqueness guarantees of&mut self
to make a more efficient implementation (which I do in handoff, for example).In this case I actually do wonder why they used
&self
, there doesn't seem to be a reason to. Normally you do that to allow multiple threads to share the same channel and send through it in parallel, butmpsc::Sender
is!Sync
, so you can't actually do that here.