Poperton
Poperton

Reputation: 2127

Shouldn't Arc<T> implement Clone for any T?

On the code below, you can see that I'm trying to clone a: A where A derives Clone

use std::sync::Arc;

pub trait S{}

struct B{
}

impl S for B{
    
}

#[derive(Clone)]
struct A<T: ?Sized>{
    a: Arc<Box<T>>
}

fn main() {
    let a: A<dyn S> = A{
        a: Arc::new(Box::new(B{}))
    };
    
    a.clone();
    
}

Playground

However I get this error:

Error:

   Compiling playground v0.0.1 (/playground)
error[E0599]: the method `clone` exists for struct `A<dyn S>`, but its trait bounds were not satisfied
  --> src/main.rs:22:7
   |
3  | pub trait S{}
   | ----------- doesn't satisfy `dyn S: Clone`
...
13 | struct A<T: ?Sized>{
   | -------------------
   | |
   | method `clone` not found for this
   | doesn't satisfy `A<dyn S>: Clone`
...
22 |     a.clone();
   |       ^^^^^ method cannot be called on `A<dyn S>` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `dyn S: Clone`
           which is required by `A<dyn S>: Clone`
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `clone`, perhaps you need to implement it:
           candidate #1: `Clone`

Shouldn't A implement Clone for any T, since the clone on A would simply call A {a: old_a.clone()} which since it's an Arc it always implement clone?

Shouldn't it be guaranteed that A implements Clone because of #[derive(Clone)]?

Upvotes: 5

Views: 1150

Answers (1)

cadolphs
cadolphs

Reputation: 9617

This is an issue with the implementation of the derive macro for Clone. It doesn't work with structs containing generic types that don't implement clone themselves: https://github.com/rust-lang/rust/issues/41481

In that case you'll have to implement Clone manually, which is, as you say, pretty easy.

impl<T> Clone for A<T> {
  fn clone(&self) -> A<T> {
    A { a: self.a.clone() }
  }
}

Upvotes: 8

Related Questions