Uh oh!
There was an error while loading. Please reload this page.
Ignore derived Clone and Debug implementations during dead code analysis - #85200
Conversation
rust-highfive
commented
May 11, 2021
r? @lcnr (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
FabianWolff
commented
May 12, 2021
As an argument in favor of this pull request, it has already found a number of unused fields in the compiler code, breaking the bootstrap process. I have now sprinkled a few I would have preferred |
This comment has been minimized.
This comment has been minimized.
cjgillot
commented
May 12, 2021
For compiler code, it would be better just to drop the fields. For tests, it may be preferrable to add a dummy |
FabianWolff
commented
May 12, 2021
I've dropped the unused fields from the compiler code now, except for the rust/compiler/rustc_mir/src/transform/coverage/mod.rs Lines 37 to 47 in 70e52ca But the struct is used in various places where a Result is returned (e.g. here and here), so I only left a comment there for now. |
This comment has been minimized.
This comment has been minimized.
matklad
commented
May 13, 2021
Looks like I was just mistaken, the impl looks ok to me. One thing I worry is that, judging by the impact on rustc itself, this would be a noticable user-visible change (ie, big projects are guaranteed to get a couple instances of this at least). So it seems like some design process is needed here, culminating in an FCP. I don't know whats the specific appropriate process here is, so let me tag a random t-compiled lead for this: @pnkfelix. |
bors
commented
May 15, 2021
☔ The latest upstream changes (presumably #85328) made this pull request unmergeable. Please resolve the merge conflicts. |
bors
commented
May 15, 2021
☔ The latest upstream changes (presumably #85335) made this pull request unmergeable. Please resolve the merge conflicts. |
This comment has been minimized.
This comment has been minimized.
lcnr
left a comment
There was a problem hiding this comment.
I think this change makes sense. It does have some incorrect warnings if a struct adds a field solely for the sideeffects of that structs Clone impl, but that seems like a fine tradeoff to me.
It might also make sense to extend this to all impls with the syn::automatically_derived attribute. But the pattern of using fields for their behavior in derived impls is probably more prevalent for traits like Hash.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
nominated for @rust-lang/lang signoff |
scottmcm
commented
May 18, 2021
This seems good to me -- the compiler examples of how much this has been hiding is quite strong justification 👍 If a field is really only for a One thing I was pondering: What it is about |
matklad
commented
May 18, 2021
Answer, as usual, history -- it was the two traits that preventing the useful unused warning from firing in the case which prompted me to crate the issue. I think, if we are to do this, we should do this for all build-in derives at least. |
nikomatsakis
commented
May 18, 2021
I'm in favor of the concept, I think extending it to all automatically derived traits is pretty logical. |
FabianWolff
commented
May 18, 2021
Thanks for your comments everyone, and thanks for your review and suggestions @lcnr! I have implemented them now, along with the suggestion to ignore all automatically derived impls, not just those of rust/compiler/rustc_attr/src/builtin.rs Lines 597 to 601 in a5560a6 I have prefixed such field names with underscores for now to silence the warning. I think that's acceptable, because the underscore makes explicit that the field is needed only for its "side-effects" (e.g. on ordering). Also keep in mind that I have already removed most of the actually unnecessary fields in an earlier commit, so the above doesn't mean that this change causes unreasonably many false positives. |
richkadel
left a comment
There was a problem hiding this comment.
It doesn't make sense (to me) to qualify the coverage::Error struct or field. The struct and the message field are used. If Rust thinks it isn't used, then something else is wrong with how this is being compiled.
If you must annotate it to workaround another problem, maybe you can add a FIXME comment with a bug ID, so this annotation can eventually be removed?
Uh oh!
There was an error while loading. Please reload this page.
joshtriplett
commented
May 19, 2021
I do think it's appropriate to exclude Debug and Clone and similar. However, I think PartialEq and PartialOrd are actually legitimate "uses" if and only if the instances are called. It's valid to have a struct with fields that are only used in equality/ordering comparisons, and nowhere else; I think those shouldn't need an underscore. |
nikomatsakis
commented
May 19, 2021
Agree. |
nikomatsakis
left a comment
There was a problem hiding this comment.
I hadn't actually looked at the diff before, but I agree that we need to be considering PartialEq, Hash, and friends as using the fields. I think a good goal for the PR should be that "no false warnings" and right now there are a lot, but almost all seem to be linked to PartialEq / Eq / Hash.
The case of the Error struct with the message field is interesting and a bit more complex.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
FabianWolff
commented
May 19, 2021
So should I go back to just |
nikomatsakis
commented
May 21, 2021
I'm inclined to go back to an "opt-in" scheme, with just That said, this is only a lint. I think that both of those kinds of cases are ones where it'd be reasonable to put a comment explaining what the field is doing there I think the difference with (e.g.) |
FabianWolff
commented
May 21, 2021
Thanks for the clarification! I have now gone back to just |
nikomatsakis
commented
May 24, 2021
This is looking quite good to me. I'm going to go ahead and start an FCP merge. @rfcbot fcp merge |
rust-lang/rust#85200 changed rust to emit more unused warnings if fields in a struct are ultimately never read. This adds a test to make sure that we don't experience these warnings.
rust-lang/rust#85200 changed rust to emit more unused warnings if fields in a struct are ultimately never read. This adds a test to make sure that we don't experience these warnings.
shepmaster
commented
Jan 11, 2022
Is there another issue I can follow to track the stabilization of this attribute? One of my crates uses derives to create structures and those structures effectively disable the dead code lint. I believe this attribute might help me in my case. |
Add missing release notes for rust-lang#85200Fixesrust-lang#93894
Add missing release notes for rust-lang#85200Fixesrust-lang#93894
Add missing release notes for rust-lang#85200Fixesrust-lang#93894
This pull request fixes#84647. Derived implementations of
CloneandDebugalways trivially read all fields, so "field is never read" dead code warnings are never triggered. Arguably, though, a user most likely will only be interested in whether their code ever reads those fields, which is the behavior I have implemented here.Note that implementations of
CloneandDebugare only ignored if they are#[derive(...)]d; a customimpl Clone/Debug for ...will still be analyzed normally (i.e. if a customCloneimplementation uses all fields of the struct, this will continue to suppress dead code warnings about unused fields); this seemed like the least intrusive change to me (although it would be easy to change — just drop the&& [impl_]item.span.in_derive_expansion()in the if conditions).The only thing that I am slightly unsure about is that in #84647, @matklad said
However, it was pretty straightforward to fix, so did I perhaps overlook something obvious? @matklad, could you weigh in on this?