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)]?

#[derive(Clone)] only derives Clone when all of the type parameters are Clone. If you implement the clone manually for all T, it should work. The derive directives aren't very smart.

that's strange, this case is very simple. Arc implements Clone, and there's only Arc there, so it should be very very starighforward

You have T as a generic parameter, so derive(Clone) requires T: Clone (it just assumes it will need to clone a T, it doesn't see any Arc.)

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.