After think about this a little while, I think the problem is unsoundness of Cell is the source of the evil. Just think about this, having a &Cell<Option<T>> is pretty much having a &mut T, since we can do the following thing:
fn abuse_cell_ref<T>(cell_ref: &Cell<Option<T>>, op: impl FnOnce(&mut T)) {
if let Some(mut inner) = cell_ref.replace(None) {
op(&mut inner);
cell_ref.replace(Some(inner));
}
}
But the evil part is the compiler will treat this reference as normal immutable reference. You don't really have a way to clone a &mut T, but you definitely can have &Cell<Option<T>> cloned as it's just a immutable reference. And this makes multiple &mut T effectively possible in safe Rust.
So there's actually a lot of different way to exploit this. For example, I believe this code is definitely an UB, but it's completely safe code. Even without Pin, I believe.
In the code above, you are ending up a malformed b-tree data structure.
So my point is Cell really safe, the problem of Cell is it makes &T not a guarantee of immutability any more. Furthermore, most of other part of the code just believe the contract that everything behind &T is really immutable and this gives malicious code so many ways to break borrowing contract even without unsafe block.