mcarton / rust-derivative

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

Failed to derive Clone for structs with fields which have references #90

Open yubrot opened 3 years ago

yubrot commented 3 years ago

Describe the bug The following code will fail to derive.

To Reproduce

use derivative::*;

#[derive(Derivative, Debug)]
#[derivative(Clone(bound = ""), Copy(bound = ""))]
pub struct T<'a, A> {
    a: &'a String,
    b: &'a A,
}

Expected behavior derive succeeds.

Errors

error[E0308]: mismatched types
 --> src/main.rs:3:10
  |
3 | #[derive(Derivative, Debug)]
  |          ^^^^^^^^^^
  |          |
  |          expected `&String`, found struct `String`
  |          help: consider borrowing here: `&Derivative`

Version (please complete the following information):

Arnavion commented 1 year ago

This will be fixed if the macro expansion uses UFCS Clone::clone(arg) instead of arg.clone(), ie #111

As I wrote there, the macro can be forced to use UFCS by annotating the borrow fields with clone_with = "Clone::clone", which for OP's case means:

use derivative::*;

#[derive(Derivative, Debug)]
#[derivative(Clone(bound = ""), Copy(bound = ""))]
pub struct T<'a, A> {
    #[derivative(Clone(clone_with = "Clone::clone"))]
    a: &'a String,
    #[derivative(Clone(clone_with = "Clone::clone"))]
    b: &'a A,
}