skatori
skatori

Reputation: 607

How to make a trait (and a struct implementing it) clonable?

Compiling the following code, an error occurs as follows.

error[E0277]: the trait bound `dyn T: std::clone::Clone` is not satisfied
 --> src/main.rs:3:21

Please help me to fix the code.

Playground

trait T {}

#[derive(Clone)]
struct S1 { val: isize, nd:B ox<dyn T> }

#[derive(Clone)]
struct S2 { val: isize }

impl T for S1 {}
impl T for S2 {}

fn main() {
   let x2 = S2 { val: 2 };
   let x1 = S1 { val: 1, nd: Box::new(x2) };
   let x1 = x1.clone();
}

Upvotes: 4

Views: 1539

Answers (1)

Mihir Luthra
Mihir Luthra

Reputation: 6779

The compiler tells you that trait Clone is not satisfied for Box<dyn T>.

To get around this, what you can do is:

trait T: Clone {}

This will force all implementors of T to implement Clone as well.

This fixed one thing, but after doing this you will see a new error disallowing you to construct a trait object.

error[E0038]: the trait `T` cannot be made into an object
 --> /Users/mihir/fquicktest/data/user_data/instances/so_rust_q.rs:3:21
  |
3 | struct S1{val:isize,nd:Box<dyn T>,}
  |                     ^^^^^^^^^^^^^ the trait `T` cannot be made into an object
  |
  = note: the trait cannot require that `Self : Sized`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0038`.

I would really suggest that you give a read to rustc --explain E0038. It's documented really well and will explain you the situations under which you can't make trait object.

Futher, to solve this, you can use dyn-clone.

Updating you code:

use dyn_clone::DynClone;

trait T: DynClone {}
dyn_clone::clone_trait_object!(T);

#[derive(Clone)]
struct S1 {
    val: isize,
    nd: Box<dyn T>,
}
#[derive(Clone)]
struct S2 {
    val: isize,
}

impl T for S1 {}
impl T for S2 {}

fn main() {
    let x2 = S2 { val: 2 };
    let x1 = S1 {
        val: 1,
        nd: Box::new(x2),
    };
    let x1 = x1.clone();
}

There are some examples on dyn_clone docs that may help more.

Upvotes: 4

Related Questions