Skip to content

Duplicates of builtin derives with correct requirements #490

@RGBCube

Description

@RGBCube

Currently, when you do:

#[derive(Clone)]
struct Foo<T>(std::sync::Arc<T>);

struct NoClone;

fn main() {
  let foo = Foo(std::sync::Arc::new(NoClone));
  let foo_ = foo.clone();
}

link to playground

The code fails to compile. This is because the standard Clone and other derive macros that require fields to implement the trait they're deriving generate the following code: (they technically don't generate the code, but the functionality is equivalent)

impl<T> Clone for Foo<T> where
  T: Clone,
  Arc<T>: Clone,
{ ... }

Rather than:

impl<T> Clone for Foo<T> where
  Arc<T>: Clone
  /* and more, FieldT: Clone, for every field */
{ ... }

This is incorrect behaviour and makes the trait impls too narrow to be useful in many cases.

The reason for this behaviour is historical, and I don't believe it's possible to fix without a new edition, but that's far away and such a fix would break a lot of things.

It would be great if a temporary solution could be implemented in this crate to fix this, I can implement it myself if that's needed, but having this in an already widely used crate would be wonderful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions