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

Strange auto derive behaviour with associated types #33711

Closed
CasualX opened this issue May 18, 2016 · 5 comments
Closed

Strange auto derive behaviour with associated types #33711

CasualX opened this issue May 18, 2016 · 5 comments

Comments

@CasualX
Copy link

CasualX commented May 18, 2016

Auto deriving impls for a generic struct which only contains instances of associated types (not the generics themselves) unnecessarily constrains the impl for the struct.

I tried this code: https://is.gd/V6mqWI

pub trait Trait: Clone {
    type Type: Copy + Clone;
}

#[derive(Copy, Clone)]
pub struct ImplT;
impl Trait for ImplT {
    type Type = i32;
}

// Here is the problem, auto derive for `Copy` does nothing.
// What I believe is happening is that impl for `Copy` is unnecessarily constraining `T` itself must be `Copy`.
#[derive(Copy, Clone)]
pub struct NewT<T: Trait>(pub T::Type);
// Workaround:
//impl<T: Trait> Copy for NewT<T> where T::Type: Copy {}

#[derive(Clone)]
pub struct Foo<T: Trait>(T::Type);
impl<T: Trait> Foo<T> {
    pub fn get_if<F>(&self, f: F) -> Option<NewT<T>>
        where F: FnOnce(NewT<T>) -> bool {
        let newt = NewT(self.0);
        if f(newt) {
            Some(newt)
        }
        else {
            None
        }
    }
}

fn main() {
    let foo = Foo::<ImplT>(42);
    foo.get_if(|newt| true);
}

I expected to see this happen: NewT<T> is copyable.

Instead this happened:

<anon>:25:18: 25:22 error: use of moved value: `newt` [E0382]
<anon>:25             Some(newt)
                           ^~~~
<anon>:25:18: 25:22 help: see the detailed explanation for E0382
<anon>:24:14: 24:18 note: `newt` moved here because it has type `NewT<T>`, which is non-copyable
<anon>:24         if f(newt) {
                       ^~~~
error: aborting due to previous error
playpen: application terminated with error code 101

Workaround: Instead of auto deriving Copy for NewT<T>, manually implement it like so:

#[derive(Clone)]
pub struct NewT<T: Trait>(pub T::Type);
impl<T: Trait> Copy for NewT<T> where T::Type: Copy {}

Meta

I used playpen; Debug, Stable, but the same error happens with every option I select.

@apasel422
Copy link
Contributor

Similar to #23575.

@CasualX CasualX changed the title Strange auto derive behaviour with associated types Strange auto derive behaviour with associated type members May 18, 2016
@CasualX CasualX changed the title Strange auto derive behaviour with associated type members Strange auto derive behaviour with associated types May 18, 2016
@durka
Copy link
Contributor

durka commented May 18, 2016

Duplicate of #31518 (and others) I believe.

@durka
Copy link
Contributor

durka commented May 18, 2016

The built-in derives always add bounds for the derived trait on all type parameters, regardless of what's contained in the struct/enum. You can run with --pretty=expanded to see what it generates.

@CasualX
Copy link
Author

CasualX commented May 18, 2016

Thanks, my search query for derive associated type only found #23575 which talks about some fixes but I guess that's older, unrelated stuff.

@apasel422
Copy link
Contributor

Closing as duplicate.

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

3 participants