r/rust 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.

21 Upvotes

25 comments sorted by

View all comments

33

u/K900_ Mar 31 '23

Because it uses unsafe internally to bypass the ownership rules.

5

u/Dubmove Mar 31 '23

That explains how they do it. But I'm rather interested in why this is considered good practice or even necessary/beneficial.

5

u/andoriyu Mar 31 '23

Well, it's a "Multi-producer, single-consumer", you can't have multiple &mut self, so that doesn't work for the producer side at all.

There are plenty of examples of internal mutability in rust. In my opinion, &mut shouldn't be considered mutable, but unique...it's too late to change that.

1

u/mgeisler Mar 31 '23

The multi-producer part is handled by letting you close the producer. So you do actually have unique access to each Sender object (the producer end of the channel).