diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index fbbeec93c66b..0d417c25ef0e 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -268,18 +268,16 @@ fn check_replace_with_default( expr.span, "replacing a value of type `T` with `T::default()`", |diag| { - if !expr.span.from_expansion() { - let mut applicability = Applicability::MachineApplicable; - let (dest_snip, _) = snippet_with_context(cx, dest.span, expr.span.ctxt(), "", &mut applicability); - let suggestion = format!("{top_crate}::mem::take({dest_snip})"); + let mut applicability = Applicability::MachineApplicable; + let (dest_snip, _) = snippet_with_context(cx, dest.span, expr.span.ctxt(), "", &mut applicability); + let suggestion = format!("{top_crate}::mem::take({dest_snip})"); - diag.span_suggestion( - expr.span, - format!("consider using `{top_crate}::mem::take` instead"), - suggestion, - applicability, - ); - } + diag.span_suggestion( + expr.span, + format!("consider using `{top_crate}::mem::take` instead"), + suggestion, + applicability, + ); }, ); true diff --git a/tests/ui/mem_replace_with_default.fixed b/tests/ui/mem_replace_with_default.fixed index 3270964816e2..af88a473e19a 100644 --- a/tests/ui/mem_replace_with_default.fixed +++ b/tests/ui/mem_replace_with_default.fixed @@ -1,5 +1,9 @@ +//@aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; use std::mem; @@ -69,6 +73,13 @@ fn main() { //~^ mem_replace_with_default } +#[inline_macros] +fn macros(s: &mut String) { + let _ = inline!(std::mem::take($s)); + //~^ mem_replace_with_default + let _ = external!(std::mem::replace($s, Default::default())); +} + // lint is disabled for primitives because in this case `take` // has no clear benefit over `replace` and sometimes is harder to read fn dont_lint_primitive() { diff --git a/tests/ui/mem_replace_with_default.rs b/tests/ui/mem_replace_with_default.rs index ca8f0a668983..6642a8340d5f 100644 --- a/tests/ui/mem_replace_with_default.rs +++ b/tests/ui/mem_replace_with_default.rs @@ -1,5 +1,9 @@ +//@aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; use std::mem; @@ -69,6 +73,13 @@ fn main() { //~^ mem_replace_with_default } +#[inline_macros] +fn macros(s: &mut String) { + let _ = inline!(std::mem::replace($s, Default::default())); + //~^ mem_replace_with_default + let _ = external!(std::mem::replace($s, Default::default())); +} + // lint is disabled for primitives because in this case `take` // has no clear benefit over `replace` and sometimes is harder to read fn dont_lint_primitive() { diff --git a/tests/ui/mem_replace_with_default.stderr b/tests/ui/mem_replace_with_default.stderr index d0265a22e05f..8690ba4a198a 100644 --- a/tests/ui/mem_replace_with_default.stderr +++ b/tests/ui/mem_replace_with_default.stderr @@ -1,5 +1,5 @@ error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:8:13 + --> tests/ui/mem_replace_with_default.rs:12:13 | LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut s)` @@ -8,130 +8,138 @@ LL | let _ = std::mem::replace(&mut s, String::default()); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:10:13 + --> tests/ui/mem_replace_with_default.rs:14:13 | LL | let _ = std::mem::replace(&mut s, String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut s)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:14:13 + --> tests/ui/mem_replace_with_default.rs:18:13 | LL | let _ = std::mem::replace(s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:16:13 + --> tests/ui/mem_replace_with_default.rs:20:13 | LL | let _ = std::mem::replace(s, String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:18:13 + --> tests/ui/mem_replace_with_default.rs:22:13 | LL | let _ = std::mem::replace(s, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:22:13 + --> tests/ui/mem_replace_with_default.rs:26:13 | LL | let _ = std::mem::replace(&mut v, Vec::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:24:13 + --> tests/ui/mem_replace_with_default.rs:28:13 | LL | let _ = std::mem::replace(&mut v, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:26:13 + --> tests/ui/mem_replace_with_default.rs:30:13 | LL | let _ = std::mem::replace(&mut v, Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:28:13 + --> tests/ui/mem_replace_with_default.rs:32:13 | LL | let _ = std::mem::replace(&mut v, vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:32:13 + --> tests/ui/mem_replace_with_default.rs:36:13 | LL | let _ = std::mem::replace(&mut hash_map, HashMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut hash_map)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:36:13 + --> tests/ui/mem_replace_with_default.rs:40:13 | LL | let _ = std::mem::replace(&mut btree_map, BTreeMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut btree_map)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:40:13 + --> tests/ui/mem_replace_with_default.rs:44:13 | LL | let _ = std::mem::replace(&mut vd, VecDeque::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut vd)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:44:13 + --> tests/ui/mem_replace_with_default.rs:48:13 | LL | let _ = std::mem::replace(&mut hash_set, HashSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut hash_set)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:48:13 + --> tests/ui/mem_replace_with_default.rs:52:13 | LL | let _ = std::mem::replace(&mut btree_set, BTreeSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut btree_set)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:52:13 + --> tests/ui/mem_replace_with_default.rs:56:13 | LL | let _ = std::mem::replace(&mut list, LinkedList::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut list)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:56:13 + --> tests/ui/mem_replace_with_default.rs:60:13 | LL | let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut binary_heap)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:60:13 + --> tests/ui/mem_replace_with_default.rs:64:13 | LL | let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut tuple)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:64:13 + --> tests/ui/mem_replace_with_default.rs:68:13 | LL | let _ = std::mem::replace(&mut refstr, ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut refstr)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:68:13 + --> tests/ui/mem_replace_with_default.rs:72:13 | LL | let _ = std::mem::replace(&mut slice, &[]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut slice)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:99:13 + --> tests/ui/mem_replace_with_default.rs:78:21 + | +LL | let _ = inline!(std::mem::replace($s, Default::default())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take($s)` + | + = note: this error originates in the macro `__inline_mac_fn_macros` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: replacing a value of type `T` with `T::default()` + --> tests/ui/mem_replace_with_default.rs:110:13 | LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut s)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:112:13 + --> tests/ui/mem_replace_with_default.rs:123:13 | LL | let _ = std::mem::replace(&mut b.val, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut b.val)` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default.rs:118:20 + --> tests/ui/mem_replace_with_default.rs:129:20 | LL | let replaced = std::mem::replace(dbg!(&mut text), String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(dbg!(&mut text))` -error: aborting due to 22 previous errors +error: aborting due to 23 previous errors diff --git a/tests/ui/mem_replace_with_default_macro.rs b/tests/ui/mem_replace_with_default_macro.rs deleted file mode 100644 index 9458dade3a9c..000000000000 --- a/tests/ui/mem_replace_with_default_macro.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@aux-build:proc_macros.rs -#![warn(clippy::mem_replace_with_default)] - -extern crate proc_macros; -use proc_macros::{external, inline_macros}; - -#[inline_macros] -fn main() { - let s = &mut String::from("foo"); - let _ = inline!(std::mem::replace($s, Default::default())); - //~^ mem_replace_with_default - let _ = external!(std::mem::replace($s, Default::default())); -} diff --git a/tests/ui/mem_replace_with_default_macro.stderr b/tests/ui/mem_replace_with_default_macro.stderr deleted file mode 100644 index a443fc1c2fd2..000000000000 --- a/tests/ui/mem_replace_with_default_macro.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default_macro.rs:10:21 - | -LL | let _ = inline!(std::mem::replace($s, Default::default())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` - = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error - diff --git a/tests/ui/mem_replace_with_default_no_std.fixed b/tests/ui/mem_replace_with_default_no_std.fixed index 0b8171df83a7..0486bf1a173f 100644 --- a/tests/ui/mem_replace_with_default_no_std.fixed +++ b/tests/ui/mem_replace_with_default_no_std.fixed @@ -1,6 +1,10 @@ +//@aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] #![no_std] +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + use core::mem; fn it_works() { @@ -12,3 +16,10 @@ fn it_works() { let _ = core::mem::take(&mut slice); //~^ mem_replace_with_default } + +#[inline_macros] +fn macros(mut refstr: &str) { + let _ = inline!(core::mem::take(&mut $refstr)); + //~^ mem_replace_with_default + let _ = external!(mem::replace(&mut $refstr, "")); +} diff --git a/tests/ui/mem_replace_with_default_no_std.rs b/tests/ui/mem_replace_with_default_no_std.rs index 621152f01634..c2670ece76ae 100644 --- a/tests/ui/mem_replace_with_default_no_std.rs +++ b/tests/ui/mem_replace_with_default_no_std.rs @@ -1,6 +1,10 @@ +//@aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] #![no_std] +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + use core::mem; fn it_works() { @@ -12,3 +16,10 @@ fn it_works() { let _ = mem::replace(&mut slice, &[]); //~^ mem_replace_with_default } + +#[inline_macros] +fn macros(mut refstr: &str) { + let _ = inline!(mem::replace(&mut $refstr, "")); + //~^ mem_replace_with_default + let _ = external!(mem::replace(&mut $refstr, "")); +} diff --git a/tests/ui/mem_replace_with_default_no_std.stderr b/tests/ui/mem_replace_with_default_no_std.stderr index 2d1159a7e9d9..7fb72cdf5a48 100644 --- a/tests/ui/mem_replace_with_default_no_std.stderr +++ b/tests/ui/mem_replace_with_default_no_std.stderr @@ -1,5 +1,5 @@ error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default_no_std.rs:8:13 + --> tests/ui/mem_replace_with_default_no_std.rs:12:13 | LL | let _ = mem::replace(&mut refstr, ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `core::mem::take` instead: `core::mem::take(&mut refstr)` @@ -8,10 +8,18 @@ LL | let _ = mem::replace(&mut refstr, ""); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` error: replacing a value of type `T` with `T::default()` - --> tests/ui/mem_replace_with_default_no_std.rs:12:13 + --> tests/ui/mem_replace_with_default_no_std.rs:16:13 | LL | let _ = mem::replace(&mut slice, &[]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `core::mem::take` instead: `core::mem::take(&mut slice)` -error: aborting due to 2 previous errors +error: replacing a value of type `T` with `T::default()` + --> tests/ui/mem_replace_with_default_no_std.rs:22:21 + | +LL | let _ = inline!(mem::replace(&mut $refstr, "")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `core::mem::take` instead: `core::mem::take(&mut $refstr)` + | + = note: this error originates in the macro `__inline_mac_fn_macros` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors