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?
So basically only suggest using mem::take when the replaced thing is not assigned to anything?
Exactly. Arguably clippy should suggest *thing = Thing::default() in the latter case.
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).
mem::replace(&mut thing, Thing::default());
Given that mem::replace is #[must_use] (https://github.com/rust-lang/rust/pull/71256), the usage that ignores mem::replace's return value is probably not the recommended way.
Yeah, looks like the upstream recommended way is just to assign:
*thing = Thing::default()
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.
Most helpful comment
Given that
mem::replaceis#[must_use](https://github.com/rust-lang/rust/pull/71256), the usage that ignoresmem::replace's return value is probably not the recommended way.