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

mem::replace -> mem::take lint is too aggressive #5586

Closed
benesch opened this issue May 11, 2020 · 7 comments · Fixed by #12278
Closed

mem::replace -> mem::take lint is too aggressive #5586

benesch opened this issue May 11, 2020 · 7 comments · Fixed by #12278
Assignees
Labels
C-bug Category: Clippy is not doing the correct thing good-first-issue These issues are a good way to get started with Clippy I-false-positive Issue: The lint was triggered on code it shouldn't have S-needs-discussion Status: Needs further discussion before merging or work can be started

Comments

@benesch
Copy link

benesch commented May 11, 2020

Clippy will suggest replacing

let x = mem::replace(&mut thing, Thing::default());

with:

let x = mem::take(&mut thing);

This is great! But it will also suggest replacing

mem::replace(&mut thing, Thing::default());

with:

mem::take(&mut thing);

This is not great. The construction using mem::replace in the second case is much clearer IMO as it indicates that the function is being executed for its side effects. The construction using mem::take looks like a mistake.

Would you folks be open to making the lint not apply in the second case?

@flip1995
Copy link
Member

So basically only suggest using mem::take when the replaced thing is not assigned to anything?

@flip1995 flip1995 added the S-needs-discussion Status: Needs further discussion before merging or work can be started label May 11, 2020
@benesch
Copy link
Author

benesch commented May 11, 2020

Exactly. Arguably clippy should suggest *thing = Thing::default() in the latter case.

@Luro02
Copy link

Luro02 commented May 12, 2020

This is great! But it will also suggest replacing

mem::replace(&mut thing, Thing::default());

with:

mem::take(&mut thing);

It might be useful to have a clippy lint that suggests replacing the latter with the former, because like you said the latter looks like a mistake (it is harder to read, because there is an implicit replacement of the field with default that is not obvious by the method name).

@taiki-e
Copy link
Member

taiki-e commented May 12, 2020

mem::replace(&mut thing, Thing::default());

Given that mem::replace is #[must_use] (rust-lang/rust#71256), the usage that ignores mem::replace's return value is probably not the recommended way.

@benesch
Copy link
Author

benesch commented May 12, 2020

Yeah, looks like the upstream recommended way is just to assign:

*thing = Thing::default()

@camsteffen
Copy link
Contributor

Since mem::replace was given #[must_use], perhaps the mem_replace_with_default lint should simply ignore cases where the result isn't used. The #[must_use] lint will provide the correct suggestion.

@camsteffen camsteffen added good-first-issue These issues are a good way to get started with Clippy C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Jan 26, 2021
@GabrielBFern
Copy link
Contributor

@rustbot claim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing good-first-issue These issues are a good way to get started with Clippy I-false-positive Issue: The lint was triggered on code it shouldn't have S-needs-discussion Status: Needs further discussion before merging or work can be started
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants