←back to thread

128 points RGBCube | 1 comments | | HN request time: 0.203s | source
Show context
jhugo ◴[] No.44498376[source]
> we cannot just require all generic parameters to be Clone, as we cannot assume they are used in such a way that requires them to be cloned.

No, this is backwards. We have to require all generic parameters are Clone, as we cannot assume that any are not used in a way that requires them to be Clone.

> The reason this is the way it is is probably because Rust's type system wasn't powerful enough for this to be implemented back in the pre-1.0 days. Or it was just a simple oversight that got stabilized.

The type system can't know whether you call `T::clone()` in a method somewhere.

replies(4): >>44498401 #>>44498749 #>>44499040 #>>44499325 #
1. almostdeadguy ◴[] No.44499325[source]
All the #[derive(Clone)] does is generate a trait impl of Clone for the struct, which itself can be bounded by trait constraints. It doesn't have to know that every use of the struct ensures generic parameters have to/don't have to be Clone. It doesn't have to make guarantees about how the struct is used at all.

It only needs to provide constraints that must hold for it to call clone() on each field of the struct (i.e. the constraints that must hold for the generated implementation of the fn clone(&self) method to be valid, which might not hold for all T, in which case a Struct<T> will not implement Clone). The issue this post discusses exists because there are structs like Arc<T> that are cloneable despite T not being Clone itself [1]. In a case like that it may not be desirable to put a T: Clone constraint on the trait impl, because that unnecessarily limits T where Struct<T>: Clone.

[1]: https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Clon...