Unnecessary trait bound requirement for clone

Why does the below code require T to implement clone? For a non generic Foo it has no issue, but with type parameter it fails to derive clone. Seems to me that the requirement that type parameters implement Clone is unnecessary. Would be necessary for a field of type T, but if I only use Arc there's no need for T to have trait bound.

use std::sync::Arc;

struct Foo<T>{
     _t: std::marker::PhantomData<T>
}

#[derive(Clone)]
enum Enum<T> {
    A,
    B(Arc<Foo<T>>),
}

fn bar<T>(x: Enum<T>) -> Enum<T> {
    x.clone()
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0599]: the method `clone` exists for enum `Enum<T>`, but its trait bounds were not satisfied
   --> src/lib.rs:14:7
    |
8   | enum Enum<T> {
    | ------------ method `clone` not found for this enum because it doesn't satisfy `Enum<T>: Clone`
...
14  |     x.clone()
    |       ^^^^^ method cannot be called on `Enum<T>` due to unsatisfied trait bounds
    |
note: trait bound `T: Clone` was not satisfied
   --> src/lib.rs:7:10
    |
7   | #[derive(Clone)]
    |          ^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: the method `clone` exists on the type `Arc<Foo<T>>`
   --> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/clone.rs:160:5
    |
160 |     fn clone(&self) -> Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting the type parameter to satisfy the trait bound
    |
13  | fn bar<T>(x: Enum<T>) -> Enum<T> where T: Clone {
    |                                  ++++++++++++++

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (lib) due to 1 previous error

Deriving Clone always requires that the type params implement Clone, this is just the way the derive macro works. To work around this you have to implement Clone yourself.

For some "why"s beyond historical reasons, see this blog post.

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.