2

These structs:

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Clone)]
struct Inner<T> {
    obj: Rc<RefCell<T>>,
}

#[derive(Clone)]
struct Outer {
    data: Inner<Data>,
}

struct Data {}

Give me the error:

error[E0277]: the trait bound `Data: Clone` is not satisfied
--> src\main.rs:23:2
|
23 |     data: Inner<Data>,
|     ^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
|
= note: required because of the requirements on the impl of `Clone` for `Inner<Data>`
= note: required by `clone`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

I really don't get what's wrong. Inner implements Clone, which in my head would allow Outer to implement Clone as well, but the compiler is complaining about Data. But Data is inside Rc, so it wouldn't matter whether it implements Clone or not, right?

For example, if I replace the generic T directly with Data, it compiles:

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Clone)]
struct Inner {
    obj: Rc<RefCell<Data>>,
}

#[derive(Clone)]
struct Outer {
    data: Inner,
}

struct Data {}

So why Data has to implement Clone in the first version?

I'm using Rust 1.49.0.

Edit:

This is a known compiler bug:

rodrigocfd
  • 6,450
  • 6
  • 34
  • 68
  • 1
    With `derive(Clone)` on a generic type, the compiler automatically implements `Clone` where each type parameter is also constrained to `Clone`. You will have to implement `Clone` manually in this case. – E_net4 Jan 12 '21 at 12:00

0 Answers0