darling icon indicating copy to clipboard operation
darling copied to clipboard

Running clippy pedantic on a client crate fails on stable

Open jmg-duarte opened this issue 3 years ago • 2 comments

The example is as follows:

use darling::FromMeta;

fn main() {
    println!("Hello, world!");
}

#[derive(FromMeta)]
struct Test {
    #[darling(default)]
    _argument: TOption<String>,
}

enum TOption<T> {
    Some(T),
    Default,
    None,
}

impl<T> Default for TOption<T> {
    fn default() -> Self {
        Self::None
    }
}

impl FromMeta for TOption<String> {
    /// If the input string is empty it returns `Ok(Default)`, otherwise it returns `Ok(Some(value))`.
    fn from_string(value: &str) -> darling::Result<Self> {
        if value.is_empty() {
            // arg = ""
            return Ok(Self::Default);
        }
        // arg = "..."
        Ok(Self::Some(value.to_string()))
    }

    /// Returns `Ok(Default)`.
    fn from_word() -> darling::Result<Self> {
        Ok(Self::Default)
    }
}

This is a minimized from my typestate crate. For context, TOption distinguishes a default value from "nulls" and other values.

If I run cargo clippy -- -Dclippy::pedantic on stable, it yields the following error:

error: calling `TOption::default()` is more clear than this expression
 --> src/main.rs:7:10
  |
7 | #[derive(FromMeta)]
  |          ^^^^^^^^
  |
  = note: `-D clippy::default-trait-access` implied by `-D clippy::pedantic`
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

If I run cargo +nightly clippy -- -Dclippy::pedantic, forcing nightly, no error appears.

From running cargo expand over the example we get:

// cut for brevity sake
impl ::darling::FromMeta for Test {
    fn from_list(__items: &[::syn::NestedMeta]) -> ::darling::Result<Self> {
        // cut ...
        ::darling::export::Ok(Self {
            _argument: match _argument.1 {
                ::darling::export::Some(__val) => __val,
                ::darling::export::None => ::darling::export::Default::default(),
            },
        })
    }
}
// cut ...

From clippy's link, I believe the culprit to be:

::darling::export::None => ::darling::export::Default::default(),

Which should instead be TOption::default().

I've been looking around the code but I don't really know how/where to fix this.

jmg-duarte avatar Jun 12 '21 11:06 jmg-duarte

Which should instead be TOption::default().

The code uses Default::default to avoid needing to preserve and pass around type paths when it doesn't need them, so I wouldn't fix this particular issue. However, there may still be a way to make clippy happy.

There's an attribute - I believe it's #[automatically_derived] - that some other proc-macro crates started using after darling first released. If you add that to the generated trait impl here, does that make these lint issues go away?

TedDriggs avatar Jun 24 '21 13:06 TedDriggs

I'll try and report back!

jmg-duarte avatar Jun 28 '21 10:06 jmg-duarte

Closing due to inactivity.

TedDriggs avatar Dec 28 '22 20:12 TedDriggs