Ignoring derives in unused fields lints

Would it be possible to optionally ignore uses of fields in derive macros when computing unused lints?

Real world scenario:

I have a few thousands lines of code with multiple structs that have #[derive(Debug)] slapped on them. Sometimes I need to add a new field, so I go ahead and add it. I get missing field errors in constructors (or not if they are only constructed via #[derive(Deserialize)]!) but if I forget to also read those fields (which actually happened to me a few times) I have a bug that the compiler doesn't warn me about although it could.

Minimal example:

#[derive(Debug)]
struct Foo {
    a: &'static str,
}


fn main() {
    let foo = Foo {
        a: "hello",
    };
    
    println!("{:?}", foo);
}

playground - see that the compiler doesn't warn about this

Edit: forgot to say that I'm also writing another crate where forgetting to read a field could cause vulnerabilities.

I wonder how hard would it be to get some crate-level attribute to turn this into a warning. Something like warn(field_only_read_in_derived_code) and probably also warn(field_only_read_in_derived_code(Debug)) to turn this on only for certain derives, Debug probably being the most common in practice.

Did something similar happen to you? Do you have a better idea what to do about it? I'd love to know!

4 Likes

Already implemented in nightly! It did turned up a bunch of warning all other the place, see Unactionable "field is never read" warning for printed structs with the Debug derive · Issue #88900 · rust-lang/rust · GitHub

8 Likes

Awesome, thanks for pointers! (IDK why I only noticed your comment now.)