In Rust, you can never have another reference to the value while the &mut of it is alive. It's one of the core language guarantees that makes Rust unique. There's no exception regards this rule in safe Rust. If you made an exception via some unsafe code, it's bug no matter why and how.
But sometimes we need a shared mutability. One way to implement it is to ensure the rule by some runtime check. RefCell and Mutex are examples. You can take &mut of the inner value from the & of the wrapper type, and the runtime check prevents to hold two &mut at the same time.
But there's another approach here - simply not allow to borrow the inner value. You can see that all the methods of Cell(except the .get_mut() here) takes/returns things by-value, not by-reference. Brilliant, isn't it? It's not possible to holds two &mut T from the same Cell<T> - because you can't have even one!
But all this stories are about to handle shared mutability. If you don't share(for now) the Cell<T>, nothing bad can happen when you obtain the reference of the inner value. That's why all those shared mutability types in std(Cell, RefCell, Mutex, Atomic* etc) have fn get_mut(&mut self) -> &mut T method.
And also Cell : !Sync, meaning that since it mutates through a (potentially) shared reference without any synchronization primitive, it could lead to data races if used across multiple threads. By making it !Sync, safe code is then not able to share a Cell (i.e., SendCopyies of a shared reference & _ to a Cell) across multiple threads.
You can, however, get multithread-safe by-value mutation through atomics.