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

Requires Copy constraint on parametrized struct that is already known to #[derive(Copy)] #32872

Closed
marcianx opened this issue Apr 11, 2016 · 10 comments

Comments

@marcianx
Copy link

pub trait MetaAssocTypes {
    type AssocType;
}

#[derive(Clone, Copy)]
struct IterBase<'a, Meta: MetaAssocTypes>
    where Meta::AssocType: 'a
{
    val: &'a Meta::AssocType
}

#[derive(Clone, Copy)]
pub struct FwdIter<'a, Meta: MetaAssocTypes>
    where Meta::AssocType: 'a
{
    iter: IterBase<'a, Meta>
}

fn main() {}

Playground

Private struct IterBase is known to implement Copy for all types it supports. However, #[derive(Copy)] for public struct FwdIter (which simply wraps IterBase) gives the following error:

<anon>:12:17: 12:21 error: the trait `Copy` may not be implemented for this type; field `iter` does not implement `Copy` [E0204]
<anon>:12 #[derive(Clone, Copy)]
                          ^~~~
<anon>:12:17: 12:21 note: in this expansion of #[derive_Copy] (defined in <anon>)
<anon>:12:17: 12:21 help: see the detailed explanation for E0204
error: aborting due to previous error
playpen: application terminated with error code 101

One workaround is to make IterBase public and explicitly add IterBase<'a, Meta>: Copy to the where clause of FwdIter (and all its impls).

@Aatch
Copy link
Contributor

Aatch commented Apr 11, 2016

This is a limitation of derive, you can just do impl Copy for FwdIter (with the appropriate type params added) instead.

@marcianx
Copy link
Author

I just tried that:

impl<'a, Meta: MetaAssocTypes> Copy for FwdIter<'a, Meta>
    where Meta::AssocType: 'a {}

but I received the same error on this impl line.

@Aatch
Copy link
Contributor

Aatch commented Apr 11, 2016

Ah, right, that's because the same limitation affects IterBase, it's requiring that Meta be Copy too.

@bluss
Copy link
Member

bluss commented Apr 11, 2016

And both Copy and Clone need manual implementations here. (Clone can reuse Copy though).

@marcianx
Copy link
Author

It's strange that IterBase requires Meta to be copy as IterBase it only contains a shared reference.

But sure enough, as it says https://doc.rust-lang.org/std/marker/trait.Copy.html

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.

Thanks for the clarification.

@huonw
Copy link
Member

huonw commented Apr 12, 2016

Duplicate of #26925, thanks for filing!

@huonw huonw closed this as completed Apr 12, 2016
@marcianx
Copy link
Author

@huonw My last message is related to the bug you marked this as a dupe of. But isn't the original bug reported here different? The error says

`Copy` may not be implemented for this type; field `iter` does not implement `Copy`

But it is implement right above it in my example up top. So some information is not being propagated correctly.

@huonw
Copy link
Member

huonw commented Apr 21, 2016

@marcianx, oh, sorry, you are correct that this seems different!

@huonw huonw reopened this Apr 21, 2016
@Mark-Simulacrum
Copy link
Member

So looking at the expanded code, it looks like the problem is with the impl of Copy for FwdIter. The current implementation only requires that Meta: Copy, but that doesn't mean that Meta::AssocType: Copy, which leads to this error. I think this is a bug in the derive code, but I'm not sure it's all that easy to fix--if even possible--because in order to know whether Meta::AssocType: Copy is required, you need to inspect the IterBase type to see if it uses AssocType as a field, which I don't think is possible.

I'm thinking we should close this as not really possible to fix, but since I'm uncertain, I'll leave open for the time being. Perhaps someone more familiar with this code could comment? Otherwise, I'll close in a week or two.

// current impl
impl<'a, Meta: Copy + MyTrait> Copy for FwdIter<'a, Meta>
    where Meta::AssocType: 'a { }

// required impl
impl<'a, Meta: Copy + MyTrait> Copy for FwdIter<'a, Meta>
    where Meta::AssocType: Copy + 'a { }

@Mark-Simulacrum
Copy link
Member

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

5 participants