Why is `Cell` not `Copy`?

I recently, to my surprise, learned that Cell is not Copy. Why is that? Intuitively, it seems like making it Copy is perfectly safe. Cell is not Sync, so any other access to the cell will happen from the same thread, so no mutation of the cell can happen while we copy.

On a more general note, is there any type that's Copy, bot not Send or not Sync?

Cell itself does not bind its content by Copy. Only the impl that has most functions does. This is why it is impossible in the general case to even impl<T: Copy> Copy for Cell<T> {}.

I don't understand. As you wrote, the Copy implementation could demand T to be Copy. So why has that not been done?

[quote="RalfJung, post:1, topic:2208"]
On a more general note, is there any type that's Copy, bot not Send or not Sync?
[/quote]&T where T isn't Sync.


It seems like having a Cell itself be Copy would kind of be a footgun. If you copied a cell, and mutated the contents of the new Cell, the original cell would remain unchanged.

It seems like that would be very unintuitive, as Cell is something which is meant to allow interior mutability.

For instance, if Cell was Copy, this code would have a very unintuitive affect:

let x = Cell::new(3);

let y = x;


println!("{}", x); // 3, not 5

I think this confusing behavior is the main reason it isn't implemented. If you need to make a new cell from the inner value, just use Cell::new(cell.get()) manually. It's more explicit and doesn't have any footguns.

1 Like

OK, but that doesn't explain why the trait bound is only on the inherent impl as opposed to on the struct and its impl.

The usability explanation is a good one - that sounds like it could be the actual reason. Notice that Cell is clone (and the implementation is exactly what you propose).

Regarding the trait bound, I guess there's just no reason to also add the bound to the type. It wouldn't help anybody either, would it?

1 Like

I think there's just some preference to only bind structs/methods by traits where the trait is actually used. It isn't especially useful at all to have a Cell of a non-Copy type, but I guess there isn't really any reason to dis-allow it.

There are several types in Rust that aren't marked as Copy that could be
because it might be trouble: Cell, (0..10), XorShiftRNG, ...