Why can't this clone?


#1

Here is a minimal failure case:


pub trait EnvBaseT {
    type Storage: Clone;
}

#[derive(Clone)]
pub struct Ten<Env: EnvBaseT> {
    pub storage: Env::Storage,
}

impl<Env: EnvBaseT> Ten<Env> {
    pub fn new() -> Ten<Env> {
        panic!()
    }
}


pub trait EnvT : EnvBaseT + Sized {
    fn foo(x: Ten<Self>) {
        let y = x.clone();
    }
}

Here is the error I get:

7  | pub struct Ten<Env: EnvBaseT> {
   | ----------------------------- method `clone` not found for this
...
20 |         let y = x.clone();
   |                   ^^^^^
   |
   = note: the method `clone` exists but the following trait bounds were not satisfied:
           `Ten<Self> : std::clone::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: `std::clone::Clone`

Here is why I think it should work:

EnvBaseT says that Storage supports Clone.

Then, on struct Ten, we say that Env satisfies trait EnvBaseT
Therefore, we should be able to clone “storage”
Then, we have #[derive(Clone)] which should auto derive Clone for the entire struct.

  1. Where is my logic wrong?

  2. How do we fix this?


#2

Deriving Clone will require that Env generic type itself is Clone, which it isn’t (only its associated type is). So you can impl Clone manually for Ten here instead.


#3

@vitalyd : That makes sense. Everything works now. Thanks!


#4

This is related to issue #26925.