Copy bound on type parameters

In How can I implement Copy? documentation there's a note after the code that says,

There is a small difference between the two: the derive strategy will also place a Copy bound on type parameters, which isn't always desired.

Can someone explain what is meant by - "the derive strategy will also place a Copy bound on type parameters" ?

That's to say that the following:

#[derive(Copy)]
struct Foo<T> {
    _f: PhantomData<T>
}

Results in the following:

impl<T> Copy for Foo<T>
    where T: Copy {}

Even though for all T, it's perfectly fine to copy PhantomData<T>.

This can be expanded to things other than PhantomData, like fn(T) and friends.

I think I have understood it a little bit. I am not well versed with the where syntax, so I tried the below snippets:

struct Person<T> {
    age: u32,
    gender: T
}

impl<T> Copy for Person<T> {}

#[derive(Copy, Clone)]
struct Person<T> {
    age: u32,
    gender: T
}

In the first snippet, the compiler complains that "the trait Copy may not be implemented for type(Gender)".
The second snippet doesn't raise any errors. So, does that mean using the derive approach implicitly applies Copy trait to the fields of a struct.

No, it restricts the implementation based on the named trait parameters. As most trait parameters represent field types, this is usually what you want. Sometimes, however, the field that uses the trait parameter implements Copy even when the parameter doesn't. For example, this is only Copy if T:Copy:

#[derive(Copy,Clone)]
struct MyRef<'a, T:'a>(&'a T);

But that's not strictly necessary, as references always implement Copy. If you have a MyRef<Mutex<...>>, for example, you wouldn't be able to copy or clone it. In this case, you'd probably want to write:

struct MyRef<'a, T:'a>(&'a T);

impl<'a, T:'a> Copy for MyRef<'a, T> {}
impl<'a, T:'a> Clone for MyRef<'a, T> {
    fn clone(&self)->Self { self }
}

#[derive(Copy)] adds a where clause for every generic argument, so there's a hidden where T: Copy in there.

Thanks @kornel and @2e71828

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.