Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derive Clone not working with struct containing generic type not implementing Clone #41481

Closed
antoyo opened this issue Apr 23, 2017 · 5 comments

Comments

@antoyo
Copy link
Contributor

antoyo commented Apr 23, 2017

Hello.
The following code:

use std::rc::Rc;

struct NonCloneI32(i32);

#[derive(Clone)]
struct Generic<T> {
    value: Rc<T>,
}

/*impl<T> Clone for Generic<T> {
    fn clone(&self) -> Self {
        Generic {
            value: self.value.clone(),
        }
    }
}*/

fn main() {
    let gen: Generic<NonCloneI32> = Generic {
        value: Rc::new(NonCloneI32(42)),
    };
    let gen2: Generic<NonCloneI32> = gen.clone();
}

causes the following compiler error:

error: no method named `clone` found for type `Generic<NonCloneI32>` in the current scope
  --> src/main.rs:22:42
   |
22 |     let gen2: Generic<NonCloneI32> = gen.clone();
   |                                          ^^^^^
   |
   = note: the method `clone` exists but the following trait bounds were not satisfied: `NonCloneI32 : std::clone::Clone`
   = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `clone`, perhaps you need to implement it:
   = help: candidate #1: `std::clone::Clone`

But I believe it should work as I can write the impl myself (commented in the code above) and Rc is Clone.

The same error is triggered on versions rustc 1.16.0 (30cf806ef 2017-03-10) and rustc 1.18.0-nightly (bbdaad0dc 2017-04-14).

Thanks to fix this issue.

@durka
Copy link
Contributor

durka commented Apr 23, 2017

This is a known issue. #[derive(Clone)] adds an implementation of Clone that is conditional on all the type parameters also implementing Clone.

This is the only way to do it without sometimes generating code that wouldn't compile due to well-formedness or privacy errors, so it's unlikely to be fixed in the standard library AFAIK. However there is a macro library called derivative that lets you override the bounds, so you can write e.g. #[derive(Clone(bound=""))].

@TedDriggs
Copy link

See #26925

@dimbleby
Copy link

Also #40754

@leoyvens
Copy link
Contributor

Ping the merciless triager and issue slayer @Mark-Simulacrum! Can we close this as a dupe?

@Mark-Simulacrum
Copy link
Member

Yeah, I think so. Closing in favor of #26925.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants