This may well have been done before, though I couldn't find anything. Basically, add a BoxedClone trait of the form

trait BoxedClone {
    fn box_clone(&self) -> Box<Self>;

It can be auto implemented, though we should get specialization sorted first

impl<T: Clone> BoxedClone for T {
    fn box_clone(&self) -> Box<Self> {
        box self.clone()

The reason we need this trait is for trait objects. Currently, a trait that extends Clone isn't object-safe, because there's no way to return Self directly. Thus, many people use this trait anyway.

Actually, alternatively, this could just be a default method on Clone itself. Thus we don't need to wait for specialization, and it makes sense to be here.


Your BoxedClone is also not object-safe (playground example) because it uses Self in the return type position. What people usually write is a variation of your code where Self is replaced by the trait object of the trait that should extend BoxedClone. This however makes it specific to each usage.

You could use a generic parameter and bound it with Unsize (playground example), however you won't be able to use it as supertrait because it will create a cycle (playground example).

There's already a crate for this.

1 Like

I think the point is not the exact signature of the trait, but rather that it should be included in std. Currently, many large crates just define their own CloneMyTrait trait, or use dyn-clone which has over 600k downloads. I think it's a reasonable suggestion for this to be included in the standard library.

Figuring out the exact signature of the trait is a prerequisite for putting it in std, and moreover why it's preferred for things which might make sense to eventually include in std to "bake" in third party crates which can evolve much more rapidly than std.

I haven't done a deep dive on dyn-clone but its ergonomics look like they leave a little bit to be desired, to the point there's a dyn-clonable wrapper crate which tries to simplify things using an attribute-based proc macro. And while that macro does seem to make the ergonomics a lot better, I wonder if there is a simpler solution with better ergonomics but less complexity.