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

Deriving Clone in structs with unions inside expect type parameters to be Clone, unlike structs. #36640

Closed
emilio opened this issue Sep 22, 2016 · 6 comments

Comments

@emilio
Copy link
Contributor

emilio commented Sep 22, 2016

Version: rustc 1.13.0-nightly (c772948 2016-09-20)

Test case:

#![feature(untagged_unions)]

#[repr(C)]
#[derive(Copy, Clone)]
pub struct Struct<T> {
    pub inner: Union<T>,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub union Union<T> {
    pub foo: *mut (),
    pub _phantom_0: ::std::marker::PhantomData<T>,
}

URL: https://is.gd/snf8Kb

Note that replacing the union for an struct works fine.

Result

error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 --> <anon>:6:5
  |
6 |     pub inner: Union<T>,
  |     ^^^^^^^^^^^^^^^^^^^ trait `T: std::marker::Copy` not satisfied
  |
  = help: consider adding a `where T: std::marker::Copy` bound
  = note: required because of the requirements on the impl of `std::clone::Clone` for `Union<T>`
  = note: required by `std::clone::Clone::clone`

Expected

No errors.

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 22, 2016

This is a consequence of some more general problem: #26925

Clone can be derived only for Copy unions and derived Copy impls require type parameters to be Copy.
How this can be fixed: 1) rust-lang/rfcs#1671 needs to be accepted 2) derive needs to generate per-field where clauses (for all i FieldType_i: DerivedTrait) instead of bounds on type parameters.

@petrochenkov
Copy link
Contributor

Workaround: implement Copy and Clone for Union manually without requiring any bounds on T.

@emilio
Copy link
Contributor Author

emilio commented Sep 23, 2016

Hm... the derive part standalone works fine, the part that doesn't is when it's used inside a struct.

I mean, I understand why the bound needs to be there conceptually, but this works fine with structs (which AFAIK have the same limitation), so I assume there are differences in the generated derive code for them?

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 23, 2016

@emilio

I assume there are differences in the generated derive code for them?

Yes, structs don't need to be Copy for Clone to be derivable, so derive doesn't generate Copy bounds on their type parameters.

@emilio
Copy link
Contributor Author

emilio commented Sep 23, 2016

Gah, oh, I see, that's annoying for my use case (where I always derive both of them). Thanks for the reply, though arguably I should have read more carefully.

@Mark-Simulacrum
Copy link
Member

Going to close in favor of #26925 -- since that's the underlying cause of this issue.

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