-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ignore derived Clone and Debug implementations during dead code analysis #85200
Conversation
r? @lcnr (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
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.
For compiler code, it would be better just to drop the fields. For tests, it may be preferrable to add a dummy |
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.
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. |
☔ The latest upstream changes (presumably #85328) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
.
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
Outdated
Show resolved
Hide resolved
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
Outdated
Show resolved
Hide resolved
src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
Outdated
Show resolved
Hide resolved
src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
Outdated
Show resolved
Hide resolved
nominated for @rust-lang/lang signoff |
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 |
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. |
I'm in favor of the concept, I think extending it to all automatically derived traits is pretty logical. |
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
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. |
Agree. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
So should I go back to just |
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.) |
Thanks for the clarification! I have now gone back to just |
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.
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#85200 Fixes rust-lang#93894
Add missing release notes for rust-lang#85200 Fixes rust-lang#93894
Add missing release notes for rust-lang#85200 Fixes rust-lang#93894
…askrgr Rollup of 7 pull requests Successful merges: - rust-lang#91908 (Add 2 tests) - rust-lang#93595 (fix ICE when parsing lifetime as function argument) - rust-lang#93757 (Add some known GAT bugs as tests) - rust-lang#93759 (Pretty print ItemKind::Use in rustfmt style) - rust-lang#93897 (linkchecker: fix panic on directory symlinks) - rust-lang#93898 (tidy: Extend error code check) - rust-lang#93928 (Add missing release notes for rust-lang#85200) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This code hasn't changed, but the warnings are new in Rust 1.57 because of "ignore derived Clone and Debug implementations during dead code analysis"[1]. Rust now doesn't count its generated derive code as a use of these fields, revealing that they're not actually needed. Sure enough, removing them compiles successfully and passes tests. [1] rust-lang/rust#85200
Upstream rustc has expanded the unused field lint to to not count usages performed by derived Clone and Debug implementations. rust-lang/rust#85200 This CL marks such fields with an #[allow(unused)] tag. Bug: 84550 Change-Id: Ie5a84dd7c941b47419eb2a011a8daed22fc16695 Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/581062 Fuchsia-Auto-Submit: Adrian Danis <[email protected]> Commit-Queue: Auto-Submit <[email protected]> Reviewed-by: Tyler Mandry <[email protected]>
The warnings in slasher::status seem to be the result of 2 changes: - rust-lang/rust#85200 - rust-lang/rust#118297
This pull request fixes #84647. Derived implementations of
Clone
andDebug
always 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
Clone
andDebug
are only ignored if they are#[derive(...)]
d; a customimpl Clone/Debug for ...
will still be analyzed normally (i.e. if a customClone
implementation 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?