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

Incorrect #derive(Clone, Copy) for structs containing references #117747

Closed
StyMaar opened this issue Nov 9, 2023 · 1 comment
Closed

Incorrect #derive(Clone, Copy) for structs containing references #117747

StyMaar opened this issue Nov 9, 2023 · 1 comment
Labels
C-bug Category: This is a bug.

Comments

@StyMaar
Copy link

StyMaar commented Nov 9, 2023

Shared references are Copy no matter what they point to, so deriving copy on a struct containing such a reference works fine:

#[derive(Clone, Copy)]
struct Foo<'a, T>(&'a T);

Then, because Foo now implements Copy, I expected this to work

fn toto<'a, T>(obj: &Foo<'a, T>) -> Foo<'a, T>{
    *obj
}

Instead, this happens:

error[E0507]: cannot move out of `*obj` which is behind a shared reference
  --> src/lib.rs:16:5
   |
16 |     *obj
   |     ^^^^ move occurs because `*obj` has type `Foo<'_, T>`, which does not implement the `Copy` trait

Meta

This is reproduced on stable 1.73.0, and on nightly on the playground

Additional note:

If I add the T: Copy bound, the compiler stops complaining, but it shouldn't be needed (and in practice my types themselves aren't even Copy)

Edit:

The macro expansion seems to be the source of the problem, inserting a gratuitous Clone and Copy bounds to the generic parameter.

struct Foo<'a, T>(&'a T);
#[automatically_derived]
impl<'a, T: ::core::clone::Clone> ::core::clone::Clone for Foo<'a, T> {
    #[inline]
    fn clone(&self) -> Foo<'a, T> {
        Foo(::core::clone::Clone::clone(&self.0))
    }
}
#[automatically_derived]
impl<'a, T: ::core::marker::Copy> ::core::marker::Copy for Foo<'a, T> {}

Whereas manually implementing Clone and Copy works fine as expected

impl<'a, T> Clone for Foo<'a, T> {
    #[inline]
    fn clone(&self) -> Foo<'a, T> {
        Foo(self.0)
    }
}
impl<'a, T> Copy for Foo<'a, T> {}
@StyMaar StyMaar added the C-bug Category: This is a bug. label Nov 9, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 9, 2023
@StyMaar StyMaar changed the title Confused compiler when deriving Copy for struct containing references Confused compiler when deriving Clone and Copy for struct containing references Nov 9, 2023
@StyMaar StyMaar changed the title Confused compiler when deriving Clone and Copy for struct containing references Incorrect #derive(Clone, Copy)` for structs containing references Nov 9, 2023
@StyMaar StyMaar changed the title Incorrect #derive(Clone, Copy)` for structs containing references Incorrect #derive(Clone, Copy)` for structs containing references Nov 9, 2023
@StyMaar StyMaar changed the title Incorrect #derive(Clone, Copy)` for structs containing references Incorrect #derive(Clone, Copy) for structs containing references Nov 9, 2023
@fmease
Copy link
Member

fmease commented Nov 9, 2023

You are basically looking for perfect derive:

Closing as duplicate of issue #26925.

@fmease fmease closed this as not planned Won't fix, can't repro, duplicate, stale Nov 9, 2023
@fmease fmease removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants