mcarton / rust-derivative

A set of alternative `derive` attributes for Rust
Apache License 2.0
420 stars 46 forks source link

Lifetime-aware Clone #105

Open alxiong opened 2 years ago

alxiong commented 2 years ago

Describe the bug Current #[derivative(Clone)] does not work on struct with specific lifetime

To Reproduce

#[macro_use]
extern crate derivative;

#[derive(Derivative)]
#[derivative(Clone)]
struct MyStruct<'a> {
    pub borrowed: &'a String,
}

will give:

  --> src/main.rs:45:10
   |
45 | #[derive(Derivative)]
   |          ^^^^^^^^^^ expected `&String`, found struct `String`
   |
   = note: this error originates in the derive macro `Derivative` (in Nightly builds, run with -Z macro-backtrace for more info)

Expected behavior Here's what current version of macro expands to:

#[allow(unused_qualifications)]
impl<'a> ::core::clone::Clone for MyStruct<'a> {
    fn clone(&self) -> Self {
        match *self {
            MyStruct {
                borrowed: ref __arg_0,
            } => MyStruct {
                borrowed: (*__arg_0).clone(),
            },
        }
    }
}

what we need:

impl<'a> Clone for MyStruct<'a> {
    fn clone(&self) -> Self {
        Self {
            borrowed: self.borrowed, // instead of the default, which is: `self.borrowed.clone()`
        }
    }
}

Thanks!

toyboot4e commented 2 years ago

Interesting! Something like <#FieldType as Clone>::clone(#field_ref) needs to be produced.