The authors wanted the channel to take a
&self method, because such methods are much more convenient to call. An
&mut self reference requires you to prove to the compiler that you have exclusive access to the element, but
&self does not.
As for when you can use
UnsafeCell, well you are not allowed to modify a value from multiple threads at the same time, so the surrounding API has to somehow make that impossible to happen. In the case of an mpsc channel, this is enforced because the type is not
Sync. Another solution to this problem is a
Mutex, which uses a lock to have threads wait for each other, ensuring that only one of them can access it at the time.
There are also non-thread related problems with
UnsafeCell. E.g. consider if
Vec had a
&self clear method:
let vec = vec![1, 2, 3];
let ref_1 = &vec;
Normally this is prevented by the compiler because
&mut self, but if
clear only requires an immutable reference, the compiler will allow the above code even though it lets you use a value after it is destroyed.
Any use of
UnsafeCell has to make sure either kind of problem cannot happen.