Why does Cell require Copy instead of Clone?

The semantic difference is really mainly a consequence of the Copy trait's guarantees: both a copy and a move are identical (always byte copies), so a type implementing Copy says that the source of such a "move/copy" is safe to continue using. That is, that Copy is a valid way to duplicate the value.

Unfortunately that isn't quite enough. For instance, my example fails in the same way with Rc instead of &'a:

// the "magic" type
struct BadClone {
    data: i32,
    pointer: Rc<Cell<Option<BadClone>>>,
}

impl Clone for BadClone {
    fn clone(&self) -> BadClone {
        // grab a reference to our internals
        let data: &i32 = &self.data;
        // what is it?
        println!("before: {}", *data);
        
        // now clear out the cell we point to...
        self.pointer.set(None); 
        
        // print it again (should be no change!)
        println!("after: {}", *data);

        BadClone { data: self.data, pointer: self.pointer.clone() }
    }
}

fn main() {
    let cell = Rc::new(Cell::new(None));
    cell.set(Some(BadClone {
        data: 12345678,
        pointer: cell.clone(),
    }));
    

    cell.get();
}

(In fact it is slightly worse on the playpen: it also segfaults.)

I think (but don't know, since there's no description from them) @eefriedman's example was using the panic as a proxy for "bad stuff would happen", if the RefCell was replaced with UnsafeCell (as in the real Cell or my reimplementation)---which doesn't have the dynamic checks of RefCell---the problem wouldn't have been caught in such an obvious way, leading to undefined behaviour/memory corruption as in my versions.