Skip to content
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

add lint for recreation of an entire struct #12772

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

phi-gamma
Copy link

This lint makes Clippy warn about situations where an owned struct is
essentially recreated by moving all its fields into a new instance of
the struct. The lint is not machine-applicable because the source
struct may have been partially moved.

This lint originated in something I spotted during peer review. While
working on their branch a colleague ended up with a commit where a
function returned a struct that 1:1 replicated one of its owned inputs
from its members. Initially I suspected they hadn’t run their code
through Clippy but AFAICS there is no lint for this situation yet.

changelog: new lint: [redundant_owned_struct_recreation]

New lint checklist

  • [+] Followed [lint naming conventions][lint_naming]
  • [+] Added passing UI tests (including committed .stderr file)
  • [+] cargo test passes locally
  • [+] Executed cargo dev update_lints
  • [+] Added lint documentation
  • [+] Run cargo dev fmt

@rustbot
Copy link
Collaborator

rustbot commented May 7, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @y21 (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 7, 2024
@phi-gamma
Copy link
Author

Hi, is there a way to tell in a late pass whether one or more
of a struct’s members have been moved? That might enable
machine-applicability of this lint.

@y21
Copy link
Member

y21 commented May 7, 2024

This might be better as an addition to the unnecessary_struct_initialization lint. It has essentially the same idea as this one, except it only emits a warning for Foo { ..foo } (w/o any fields), so it could be improved to also emit a warning if all fields copy from the base.

In particular, this lint also suffers from the same issues that that other lint does, which is that struct reinitialization only requires the fields to be Copy, whereas this lint's suggestion forces a move of the whole struct, which, if the value is later used again doesn't work if the struct is not Copy, and is also the reason why that other lint is in nursery (#10547 is the issue).

@phi-gamma
Copy link
Author

phi-gamma commented May 7, 2024 via email

@y21
Copy link
Member

y21 commented May 7, 2024

I thought about this for a bit and yeah, I think restricting it to only Copy types probably fixes the linked issue, but it might also regress too many "true positives" where a warning would be fine.

Maybe what we could do to avoid false positives while still warning on some useful cases would be to not emit a warning if:

  • the struct itself is not Copy
  • but any of its fields are

My reasoning is that if the struct is not Copy and none of its fields are, then Foo { bar: foo.bar }; also moves the entire struct effectively just like foo; does and in either case no fields are accessible afterwards, so the suggested code shouldn't result in more errors. If however there is one Copy field and one non-Copy field, then Foo { bar: foo.bar, baz: foo.baz }; would still allow using the Copy field whereas foo; again makes it inaccessible.


However I think for the purposes of this PR it would be easier to just not worry about the possible false positives that had already existed and only extend the unnecessary_struct_initialization lint to also catch Foo { bar: foo.bar } (in addition to what it already does).

Fixing those false positives could be done separately and the lint is in the nursery category, so that's fine.

@phi-gamma
Copy link
Author

phi-gamma commented May 8, 2024 via email

This lint makes Clippy warn about situations where an owned
struct is essentially recreated by moving all its fields into a
new instance of the struct.

Clippy will suggest to simply use the original struct. The lint
is not machine-applicable because the source struct may have been
partially moved.
@phi-gamma phi-gamma force-pushed the redundant-struct-recreation branch from b8f8654 to 3119797 Compare May 16, 2024 10:30
@phi-gamma phi-gamma force-pushed the redundant-struct-recreation branch from 3119797 to 97c8880 Compare May 16, 2024 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants