diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 43f0e5f8b639..fbbeec93c66b 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -145,7 +145,7 @@ fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &E MEM_REPLACE_OPTION_WITH_NONE, expr_span, "replacing an `Option` with `None`", - "consider `Option::take()` instead", + "consider using `Option::take()` instead", format!( "{}.take()", Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), "", &mut applicability).maybe_paren() @@ -177,7 +177,7 @@ fn check_replace_option_with_some( MEM_REPLACE_OPTION_WITH_SOME, expr_span, "replacing an `Option` with `Some(..)`", - "consider `Option::replace()` instead", + "consider using `Option::replace()` instead", format!( "{}.replace({})", Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), "_", &mut applicability).maybe_paren(), @@ -203,7 +203,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<' MEM_REPLACE_WITH_UNINIT, expr_span, "replacing with `mem::MaybeUninit::uninit().assume_init()`", - "consider using", + format!("consider using `{top_crate}::ptr::read` instead"), format!( "{top_crate}::ptr::read({})", snippet_with_applicability(cx, dest.span, "", &mut applicability) @@ -226,7 +226,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<' MEM_REPLACE_WITH_UNINIT, expr_span, "replacing with `mem::uninitialized()`", - "consider using", + format!("consider using `{top_crate}::ptr::read` instead"), format!( "{top_crate}::ptr::read({})", snippet_with_applicability(cx, dest.span, "", &mut applicability) @@ -266,16 +266,19 @@ fn check_replace_with_default( cx, MEM_REPLACE_WITH_DEFAULT, expr.span, - format!( - "replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`" - ), + "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})"); - diag.span_suggestion(expr.span, "consider using", suggestion, applicability); + diag.span_suggestion( + expr.span, + format!("consider using `{top_crate}::mem::take` instead"), + suggestion, + applicability, + ); } }, ); diff --git a/tests/ui/mem_replace.stderr b/tests/ui/mem_replace.stderr deleted file mode 100644 index bc374930cf0f..000000000000 --- a/tests/ui/mem_replace.stderr +++ /dev/null @@ -1,191 +0,0 @@ -error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:13:13 - | -LL | let _ = mem::replace(&mut an_option, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` - | - = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:16:13 - | -LL | let _ = mem::replace(an_option, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:22:13 - | -LL | let _ = std::mem::replace(&mut s, String::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` - | - = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:24:13 - | -LL | let _ = std::mem::replace(&mut s, String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:28:13 - | -LL | let _ = std::mem::replace(s, String::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:30:13 - | -LL | let _ = std::mem::replace(s, String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:32:13 - | -LL | let _ = std::mem::replace(s, Default::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:36:13 - | -LL | let _ = std::mem::replace(&mut v, Vec::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:38:13 - | -LL | let _ = std::mem::replace(&mut v, Default::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:40:13 - | -LL | let _ = std::mem::replace(&mut v, Vec::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:42:13 - | -LL | let _ = std::mem::replace(&mut v, vec![]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:46:13 - | -LL | let _ = std::mem::replace(&mut hash_map, HashMap::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:50:13 - | -LL | let _ = std::mem::replace(&mut btree_map, BTreeMap::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:54:13 - | -LL | let _ = std::mem::replace(&mut vd, VecDeque::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:58:13 - | -LL | let _ = std::mem::replace(&mut hash_set, HashSet::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:62:13 - | -LL | let _ = std::mem::replace(&mut btree_set, BTreeSet::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:66:13 - | -LL | let _ = std::mem::replace(&mut list, LinkedList::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:70:13 - | -LL | let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:74:13 - | -LL | let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:78:13 - | -LL | let _ = std::mem::replace(&mut refstr, ""); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:82:13 - | -LL | let _ = std::mem::replace(&mut slice, &[]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:115:13 - | -LL | let _ = std::mem::replace(&mut s, String::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:146:13 - | -LL | let _ = std::mem::replace(&mut f.0, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:148:13 - | -LL | let _ = std::mem::replace(&mut *f, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:150:13 - | -LL | let _ = std::mem::replace(&mut b.opt, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:153:13 - | -LL | let _ = std::mem::replace(&mut b.val, String::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` - -error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:160:20 - | -LL | let replaced = mem::replace(&mut an_option, Some(1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` - | - = note: `-D clippy::mem-replace-option-with-some` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]` - -error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:164:20 - | -LL | let replaced = mem::replace(an_option, Some(1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` - -error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:169:20 - | -LL | let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)` - -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:181:20 - | -LL | let replaced = std::mem::replace(dbg!(&mut text), String::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(dbg!(&mut text))` - -error: aborting due to 30 previous errors - diff --git a/tests/ui/mem_replace_no_std.fixed b/tests/ui/mem_replace_no_std.fixed deleted file mode 100644 index 4e2d413af6cd..000000000000 --- a/tests/ui/mem_replace_no_std.fixed +++ /dev/null @@ -1,84 +0,0 @@ -#![allow(unused, clippy::needless_lifetimes)] -#![warn( - clippy::style, - clippy::mem_replace_option_with_none, - clippy::mem_replace_with_default -)] -#![feature(lang_items)] -#![no_std] - -use core::mem; -use core::panic::PanicInfo; - -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} - -#[panic_handler] -fn panic(info: &PanicInfo) -> ! { - loop {} -} - -fn replace_option_with_none() { - let mut an_option = Some(1); - let _ = an_option.take(); - //~^ mem_replace_option_with_none - let an_option = &mut Some(1); - let _ = an_option.take(); - //~^ mem_replace_option_with_none -} - -fn replace_with_default() { - let mut refstr = "hello"; - let _ = core::mem::take(&mut refstr); - //~^ mem_replace_with_default - - let mut slice: &[i32] = &[1, 2, 3]; - let _ = core::mem::take(&mut slice); - //~^ mem_replace_with_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() { - let mut pbool = true; - let _ = mem::replace(&mut pbool, false); - - let mut pint = 5; - let _ = mem::replace(&mut pint, 0); -} - -fn main() {} - -fn issue9824() { - struct Foo<'a>(Option<&'a str>); - impl<'a> core::ops::Deref for Foo<'a> { - type Target = Option<&'a str>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl<'a> core::ops::DerefMut for Foo<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - - struct Bar { - opt: Option, - val: u8, - } - - let mut f = Foo(Some("foo")); - let mut b = Bar { opt: Some(1), val: 12 }; - - // replace option with none - let _ = f.0.take(); - //~^ mem_replace_option_with_none - let _ = (*f).take(); - //~^ mem_replace_option_with_none - let _ = b.opt.take(); - //~^ mem_replace_option_with_none - // replace with default - let _ = mem::replace(&mut b.val, u8::default()); -} diff --git a/tests/ui/mem_replace_no_std.rs b/tests/ui/mem_replace_no_std.rs deleted file mode 100644 index c0892304aba8..000000000000 --- a/tests/ui/mem_replace_no_std.rs +++ /dev/null @@ -1,84 +0,0 @@ -#![allow(unused, clippy::needless_lifetimes)] -#![warn( - clippy::style, - clippy::mem_replace_option_with_none, - clippy::mem_replace_with_default -)] -#![feature(lang_items)] -#![no_std] - -use core::mem; -use core::panic::PanicInfo; - -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} - -#[panic_handler] -fn panic(info: &PanicInfo) -> ! { - loop {} -} - -fn replace_option_with_none() { - let mut an_option = Some(1); - let _ = mem::replace(&mut an_option, None); - //~^ mem_replace_option_with_none - let an_option = &mut Some(1); - let _ = mem::replace(an_option, None); - //~^ mem_replace_option_with_none -} - -fn replace_with_default() { - let mut refstr = "hello"; - let _ = mem::replace(&mut refstr, ""); - //~^ mem_replace_with_default - - let mut slice: &[i32] = &[1, 2, 3]; - let _ = mem::replace(&mut slice, &[]); - //~^ mem_replace_with_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() { - let mut pbool = true; - let _ = mem::replace(&mut pbool, false); - - let mut pint = 5; - let _ = mem::replace(&mut pint, 0); -} - -fn main() {} - -fn issue9824() { - struct Foo<'a>(Option<&'a str>); - impl<'a> core::ops::Deref for Foo<'a> { - type Target = Option<&'a str>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl<'a> core::ops::DerefMut for Foo<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - - struct Bar { - opt: Option, - val: u8, - } - - let mut f = Foo(Some("foo")); - let mut b = Bar { opt: Some(1), val: 12 }; - - // replace option with none - let _ = mem::replace(&mut f.0, None); - //~^ mem_replace_option_with_none - let _ = mem::replace(&mut *f, None); - //~^ mem_replace_option_with_none - let _ = mem::replace(&mut b.opt, None); - //~^ mem_replace_option_with_none - // replace with default - let _ = mem::replace(&mut b.val, u8::default()); -} diff --git a/tests/ui/mem_replace_no_std.stderr b/tests/ui/mem_replace_no_std.stderr deleted file mode 100644 index 34e81a9f0750..000000000000 --- a/tests/ui/mem_replace_no_std.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:23:13 - | -LL | let _ = mem::replace(&mut an_option, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` - | - = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:26:13 - | -LL | let _ = mem::replace(an_option, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` - -error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take` - --> tests/ui/mem_replace_no_std.rs:32:13 - | -LL | let _ = mem::replace(&mut refstr, ""); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)` - | - = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` - -error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take` - --> tests/ui/mem_replace_no_std.rs:36:13 - | -LL | let _ = mem::replace(&mut slice, &[]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:76:13 - | -LL | let _ = mem::replace(&mut f.0, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:78:13 - | -LL | let _ = mem::replace(&mut *f, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` - -error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:80:13 - | -LL | let _ = mem::replace(&mut b.opt, None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` - -error: aborting due to 7 previous errors - diff --git a/tests/ui/mem_replace_option_with_none.fixed b/tests/ui/mem_replace_option_with_none.fixed new file mode 100644 index 000000000000..9041e8595d6d --- /dev/null +++ b/tests/ui/mem_replace_option_with_none.fixed @@ -0,0 +1,42 @@ +#![warn(clippy::mem_replace_option_with_none)] + +use std::mem; + +fn main() { + let mut an_option = Some(1); + let _ = an_option.take(); + //~^ mem_replace_option_with_none + let an_option = &mut Some(1); + let _ = an_option.take(); + //~^ mem_replace_option_with_none +} + +fn issue9824() { + struct Foo<'a>(Option<&'a str>); + impl<'a> std::ops::Deref for Foo<'a> { + type Target = Option<&'a str>; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl<'a> std::ops::DerefMut for Foo<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct Bar { + opt: Option, + } + + let mut f = Foo(Some("foo")); + let mut b = Bar { opt: Some(1) }; + + let _ = f.0.take(); + //~^ mem_replace_option_with_none + let _ = (*f).take(); + //~^ mem_replace_option_with_none + let _ = b.opt.take(); + //~^ mem_replace_option_with_none +} diff --git a/tests/ui/mem_replace_option_with_none.rs b/tests/ui/mem_replace_option_with_none.rs new file mode 100644 index 000000000000..b51115f02e1b --- /dev/null +++ b/tests/ui/mem_replace_option_with_none.rs @@ -0,0 +1,42 @@ +#![warn(clippy::mem_replace_option_with_none)] + +use std::mem; + +fn main() { + let mut an_option = Some(1); + let _ = mem::replace(&mut an_option, None); + //~^ mem_replace_option_with_none + let an_option = &mut Some(1); + let _ = mem::replace(an_option, None); + //~^ mem_replace_option_with_none +} + +fn issue9824() { + struct Foo<'a>(Option<&'a str>); + impl<'a> std::ops::Deref for Foo<'a> { + type Target = Option<&'a str>; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl<'a> std::ops::DerefMut for Foo<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct Bar { + opt: Option, + } + + let mut f = Foo(Some("foo")); + let mut b = Bar { opt: Some(1) }; + + let _ = std::mem::replace(&mut f.0, None); + //~^ mem_replace_option_with_none + let _ = std::mem::replace(&mut *f, None); + //~^ mem_replace_option_with_none + let _ = std::mem::replace(&mut b.opt, None); + //~^ mem_replace_option_with_none +} diff --git a/tests/ui/mem_replace_option_with_none.stderr b/tests/ui/mem_replace_option_with_none.stderr new file mode 100644 index 000000000000..d72aef719553 --- /dev/null +++ b/tests/ui/mem_replace_option_with_none.stderr @@ -0,0 +1,35 @@ +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none.rs:7:13 + | +LL | let _ = mem::replace(&mut an_option, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `an_option.take()` + | + = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` + +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none.rs:10:13 + | +LL | let _ = mem::replace(an_option, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `an_option.take()` + +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none.rs:36:13 + | +LL | let _ = std::mem::replace(&mut f.0, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `f.0.take()` + +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none.rs:38:13 + | +LL | let _ = std::mem::replace(&mut *f, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `(*f).take()` + +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none.rs:40:13 + | +LL | let _ = std::mem::replace(&mut b.opt, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `b.opt.take()` + +error: aborting due to 5 previous errors + diff --git a/tests/ui/mem_replace_option_with_none_no_std.fixed b/tests/ui/mem_replace_option_with_none_no_std.fixed new file mode 100644 index 000000000000..a018547e920b --- /dev/null +++ b/tests/ui/mem_replace_option_with_none_no_std.fixed @@ -0,0 +1,13 @@ +#![warn(clippy::mem_replace_option_with_none)] +#![no_std] + +use core::mem; + +fn it_works() { + let mut an_option = Some(1); + let _ = an_option.take(); + //~^ mem_replace_option_with_none + let an_option = &mut Some(1); + let _ = an_option.take(); + //~^ mem_replace_option_with_none +} diff --git a/tests/ui/mem_replace_option_with_none_no_std.rs b/tests/ui/mem_replace_option_with_none_no_std.rs new file mode 100644 index 000000000000..a2cc68e49d7d --- /dev/null +++ b/tests/ui/mem_replace_option_with_none_no_std.rs @@ -0,0 +1,13 @@ +#![warn(clippy::mem_replace_option_with_none)] +#![no_std] + +use core::mem; + +fn it_works() { + let mut an_option = Some(1); + let _ = mem::replace(&mut an_option, None); + //~^ mem_replace_option_with_none + let an_option = &mut Some(1); + let _ = mem::replace(an_option, None); + //~^ mem_replace_option_with_none +} diff --git a/tests/ui/mem_replace_option_with_none_no_std.stderr b/tests/ui/mem_replace_option_with_none_no_std.stderr new file mode 100644 index 000000000000..085ef4462d5f --- /dev/null +++ b/tests/ui/mem_replace_option_with_none_no_std.stderr @@ -0,0 +1,17 @@ +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none_no_std.rs:8:13 + | +LL | let _ = mem::replace(&mut an_option, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `an_option.take()` + | + = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` + +error: replacing an `Option` with `None` + --> tests/ui/mem_replace_option_with_none_no_std.rs:11:13 + | +LL | let _ = mem::replace(an_option, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::take()` instead: `an_option.take()` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/mem_replace_option_with_some.fixed b/tests/ui/mem_replace_option_with_some.fixed new file mode 100644 index 000000000000..dc0652ae3645 --- /dev/null +++ b/tests/ui/mem_replace_option_with_some.fixed @@ -0,0 +1,25 @@ +#![warn(clippy::mem_replace_option_with_some)] + +use std::mem; + +#[clippy::msrv = "1.31"] +fn main() { + let mut an_option = Some(0); + let replaced = an_option.replace(1); + //~^ mem_replace_option_with_some + + let mut an_option = &mut Some(0); + let replaced = an_option.replace(1); + //~^ mem_replace_option_with_some + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = (if b { &mut opt1 } else { &mut opt2 }).replace(1); + //~^ mem_replace_option_with_some +} + +#[clippy::msrv = "1.30"] +fn bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace_option_with_some.rs b/tests/ui/mem_replace_option_with_some.rs new file mode 100644 index 000000000000..dca284983795 --- /dev/null +++ b/tests/ui/mem_replace_option_with_some.rs @@ -0,0 +1,25 @@ +#![warn(clippy::mem_replace_option_with_some)] + +use std::mem; + +#[clippy::msrv = "1.31"] +fn main() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); + //~^ mem_replace_option_with_some + + let mut an_option = &mut Some(0); + let replaced = mem::replace(an_option, Some(1)); + //~^ mem_replace_option_with_some + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + //~^ mem_replace_option_with_some +} + +#[clippy::msrv = "1.30"] +fn bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace_option_with_some.stderr b/tests/ui/mem_replace_option_with_some.stderr new file mode 100644 index 000000000000..a064084c5fac --- /dev/null +++ b/tests/ui/mem_replace_option_with_some.stderr @@ -0,0 +1,23 @@ +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some.rs:8:20 + | +LL | let replaced = mem::replace(&mut an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `an_option.replace(1)` + | + = note: `-D clippy::mem-replace-option-with-some` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some.rs:12:20 + | +LL | let replaced = mem::replace(an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `an_option.replace(1)` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some.rs:17:20 + | +LL | let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/mem_replace_option_with_some_no_std.fixed b/tests/ui/mem_replace_option_with_some_no_std.fixed new file mode 100644 index 000000000000..7f882519aa62 --- /dev/null +++ b/tests/ui/mem_replace_option_with_some_no_std.fixed @@ -0,0 +1,26 @@ +#![warn(clippy::mem_replace_option_with_some)] +#![no_std] + +use core::mem; + +#[clippy::msrv = "1.31"] +fn it_works() { + let mut an_option = Some(0); + let replaced = an_option.replace(1); + //~^ mem_replace_option_with_some + + let mut an_option = &mut Some(0); + let replaced = an_option.replace(1); + //~^ mem_replace_option_with_some + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = (if b { &mut opt1 } else { &mut opt2 }).replace(1); + //~^ mem_replace_option_with_some +} + +#[clippy::msrv = "1.30"] +fn bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace_option_with_some_no_std.rs b/tests/ui/mem_replace_option_with_some_no_std.rs new file mode 100644 index 000000000000..539c911a7efd --- /dev/null +++ b/tests/ui/mem_replace_option_with_some_no_std.rs @@ -0,0 +1,26 @@ +#![warn(clippy::mem_replace_option_with_some)] +#![no_std] + +use core::mem; + +#[clippy::msrv = "1.31"] +fn it_works() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); + //~^ mem_replace_option_with_some + + let mut an_option = &mut Some(0); + let replaced = mem::replace(an_option, Some(1)); + //~^ mem_replace_option_with_some + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + //~^ mem_replace_option_with_some +} + +#[clippy::msrv = "1.30"] +fn bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace_option_with_some_no_std.stderr b/tests/ui/mem_replace_option_with_some_no_std.stderr new file mode 100644 index 000000000000..67965f3335b0 --- /dev/null +++ b/tests/ui/mem_replace_option_with_some_no_std.stderr @@ -0,0 +1,23 @@ +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some_no_std.rs:9:20 + | +LL | let replaced = mem::replace(&mut an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `an_option.replace(1)` + | + = note: `-D clippy::mem-replace-option-with-some` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some_no_std.rs:13:20 + | +LL | let replaced = mem::replace(an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `an_option.replace(1)` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace_option_with_some_no_std.rs:18:20 + | +LL | let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/mem_replace.fixed b/tests/ui/mem_replace_with_default.fixed similarity index 65% rename from tests/ui/mem_replace.fixed rename to tests/ui/mem_replace_with_default.fixed index 26aa7aa1b270..3270964816e2 100644 --- a/tests/ui/mem_replace.fixed +++ b/tests/ui/mem_replace_with_default.fixed @@ -1,23 +1,9 @@ -#![allow(unused, clippy::needless_lifetimes)] -#![warn( - clippy::style, - clippy::mem_replace_option_with_none, - clippy::mem_replace_with_default -)] +#![warn(clippy::mem_replace_with_default)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; use std::mem; -fn replace_option_with_none() { - let mut an_option = Some(1); - let _ = an_option.take(); - //~^ mem_replace_option_with_none - let an_option = &mut Some(1); - let _ = an_option.take(); - //~^ mem_replace_option_with_none -} - -fn replace_with_default() { +fn main() { let mut s = String::from("foo"); let _ = std::mem::take(&mut s); //~^ mem_replace_with_default @@ -101,8 +87,6 @@ fn dont_lint_not_used() { std::mem::replace(&mut s, String::default()); } -fn main() {} - #[clippy::msrv = "1.39"] fn msrv_1_39() { let mut s = String::from("foo"); @@ -117,65 +101,18 @@ fn msrv_1_40() { } fn issue9824() { - struct Foo<'a>(Option<&'a str>); - impl<'a> std::ops::Deref for Foo<'a> { - type Target = Option<&'a str>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl<'a> std::ops::DerefMut for Foo<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - struct Bar { - opt: Option, val: String, } - let mut f = Foo(Some("foo")); let mut b = Bar { - opt: Some(1), val: String::from("bar"), }; - // replace option with none - let _ = f.0.take(); - //~^ mem_replace_option_with_none - let _ = (*f).take(); - //~^ mem_replace_option_with_none - let _ = b.opt.take(); - //~^ mem_replace_option_with_none - // replace with default let _ = std::mem::take(&mut b.val); //~^ mem_replace_with_default } -#[clippy::msrv = "1.31"] -fn mem_replace_option_with_some() { - let mut an_option = Some(0); - let replaced = an_option.replace(1); - //~^ ERROR: replacing an `Option` with `Some(..)` - - let mut an_option = &mut Some(0); - let replaced = an_option.replace(1); - //~^ ERROR: replacing an `Option` with `Some(..)` - - let (mut opt1, mut opt2) = (Some(0), Some(0)); - let b = true; - let replaced = (if b { &mut opt1 } else { &mut opt2 }).replace(1); - //~^ ERROR: replacing an `Option` with `Some(..)` -} - -#[clippy::msrv = "1.30"] -fn mem_replace_option_with_some_bad_msrv() { - let mut an_option = Some(0); - let replaced = mem::replace(&mut an_option, Some(1)); -} - fn issue15785() { let mut text = String::from("foo"); let replaced = std::mem::take(dbg!(&mut text)); diff --git a/tests/ui/mem_replace.rs b/tests/ui/mem_replace_with_default.rs similarity index 66% rename from tests/ui/mem_replace.rs rename to tests/ui/mem_replace_with_default.rs index cd675f5735a1..ca8f0a668983 100644 --- a/tests/ui/mem_replace.rs +++ b/tests/ui/mem_replace_with_default.rs @@ -1,23 +1,9 @@ -#![allow(unused, clippy::needless_lifetimes)] -#![warn( - clippy::style, - clippy::mem_replace_option_with_none, - clippy::mem_replace_with_default -)] +#![warn(clippy::mem_replace_with_default)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; use std::mem; -fn replace_option_with_none() { - let mut an_option = Some(1); - let _ = mem::replace(&mut an_option, None); - //~^ mem_replace_option_with_none - let an_option = &mut Some(1); - let _ = mem::replace(an_option, None); - //~^ mem_replace_option_with_none -} - -fn replace_with_default() { +fn main() { let mut s = String::from("foo"); let _ = std::mem::replace(&mut s, String::default()); //~^ mem_replace_with_default @@ -101,8 +87,6 @@ fn dont_lint_not_used() { std::mem::replace(&mut s, String::default()); } -fn main() {} - #[clippy::msrv = "1.39"] fn msrv_1_39() { let mut s = String::from("foo"); @@ -117,65 +101,18 @@ fn msrv_1_40() { } fn issue9824() { - struct Foo<'a>(Option<&'a str>); - impl<'a> std::ops::Deref for Foo<'a> { - type Target = Option<&'a str>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl<'a> std::ops::DerefMut for Foo<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - struct Bar { - opt: Option, val: String, } - let mut f = Foo(Some("foo")); let mut b = Bar { - opt: Some(1), val: String::from("bar"), }; - // replace option with none - let _ = std::mem::replace(&mut f.0, None); - //~^ mem_replace_option_with_none - let _ = std::mem::replace(&mut *f, None); - //~^ mem_replace_option_with_none - let _ = std::mem::replace(&mut b.opt, None); - //~^ mem_replace_option_with_none - // replace with default let _ = std::mem::replace(&mut b.val, String::default()); //~^ mem_replace_with_default } -#[clippy::msrv = "1.31"] -fn mem_replace_option_with_some() { - let mut an_option = Some(0); - let replaced = mem::replace(&mut an_option, Some(1)); - //~^ ERROR: replacing an `Option` with `Some(..)` - - let mut an_option = &mut Some(0); - let replaced = mem::replace(an_option, Some(1)); - //~^ ERROR: replacing an `Option` with `Some(..)` - - let (mut opt1, mut opt2) = (Some(0), Some(0)); - let b = true; - let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); - //~^ ERROR: replacing an `Option` with `Some(..)` -} - -#[clippy::msrv = "1.30"] -fn mem_replace_option_with_some_bad_msrv() { - let mut an_option = Some(0); - let replaced = mem::replace(&mut an_option, Some(1)); -} - fn issue15785() { let mut text = String::from("foo"); let replaced = std::mem::replace(dbg!(&mut text), String::default()); diff --git a/tests/ui/mem_replace_with_default.stderr b/tests/ui/mem_replace_with_default.stderr new file mode 100644 index 000000000000..d0265a22e05f --- /dev/null +++ b/tests/ui/mem_replace_with_default.stderr @@ -0,0 +1,137 @@ +error: replacing a value of type `T` with `T::default()` + --> tests/ui/mem_replace_with_default.rs:8:13 + | +LL | let _ = std::mem::replace(&mut s, String::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::mem::take` instead: `std::mem::take(&mut s)` + | + = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` + = 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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + diff --git a/tests/ui/mem_replace_macro.rs b/tests/ui/mem_replace_with_default_macro.rs similarity index 100% rename from tests/ui/mem_replace_macro.rs rename to tests/ui/mem_replace_with_default_macro.rs diff --git a/tests/ui/mem_replace_macro.stderr b/tests/ui/mem_replace_with_default_macro.stderr similarity index 77% rename from tests/ui/mem_replace_macro.stderr rename to tests/ui/mem_replace_with_default_macro.stderr index 0c98200bf04e..a443fc1c2fd2 100644 --- a/tests/ui/mem_replace_macro.stderr +++ b/tests/ui/mem_replace_with_default_macro.stderr @@ -1,5 +1,5 @@ -error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace_macro.rs:10:21 +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())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mem_replace_with_default_no_std.fixed b/tests/ui/mem_replace_with_default_no_std.fixed new file mode 100644 index 000000000000..0b8171df83a7 --- /dev/null +++ b/tests/ui/mem_replace_with_default_no_std.fixed @@ -0,0 +1,14 @@ +#![warn(clippy::mem_replace_with_default)] +#![no_std] + +use core::mem; + +fn it_works() { + let mut refstr = "hello"; + let _ = core::mem::take(&mut refstr); + //~^ mem_replace_with_default + + let mut slice: &[i32] = &[1, 2, 3]; + let _ = core::mem::take(&mut slice); + //~^ mem_replace_with_default +} diff --git a/tests/ui/mem_replace_with_default_no_std.rs b/tests/ui/mem_replace_with_default_no_std.rs new file mode 100644 index 000000000000..621152f01634 --- /dev/null +++ b/tests/ui/mem_replace_with_default_no_std.rs @@ -0,0 +1,14 @@ +#![warn(clippy::mem_replace_with_default)] +#![no_std] + +use core::mem; + +fn it_works() { + let mut refstr = "hello"; + let _ = mem::replace(&mut refstr, ""); + //~^ mem_replace_with_default + + let mut slice: &[i32] = &[1, 2, 3]; + let _ = mem::replace(&mut slice, &[]); + //~^ mem_replace_with_default +} diff --git a/tests/ui/mem_replace_with_default_no_std.stderr b/tests/ui/mem_replace_with_default_no_std.stderr new file mode 100644 index 000000000000..2d1159a7e9d9 --- /dev/null +++ b/tests/ui/mem_replace_with_default_no_std.stderr @@ -0,0 +1,17 @@ +error: replacing a value of type `T` with `T::default()` + --> tests/ui/mem_replace_with_default_no_std.rs:8:13 + | +LL | let _ = mem::replace(&mut refstr, ""); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `core::mem::take` instead: `core::mem::take(&mut refstr)` + | + = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` + = 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 + | +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 + diff --git a/tests/ui/mem_replace_with_uninit.fixed b/tests/ui/mem_replace_with_uninit.fixed new file mode 100644 index 000000000000..d55ac85dfc71 --- /dev/null +++ b/tests/ui/mem_replace_with_uninit.fixed @@ -0,0 +1,50 @@ +#![warn(clippy::mem_replace_with_uninit)] +#![allow( + // These get removed by the suggestion + deprecated, // for `std::mem::uninitialized` + invalid_value, + clippy::uninit_assumed_init, + + // Added because the suggestion is `std::ptr::read(&mut v)` + // (which might be considered a bug) + clippy::unnecessary_mut_passed, +)] + +use std::mem; + +fn might_panic(x: X) -> X { + // in practice this would be a possibly-panicky operation + x +} + +fn main() { + let mut v = vec![0i32; 4]; + // the following is UB if `might_panic` panics + unsafe { + let taken_v = std::ptr::read(&mut v); + //~^ mem_replace_with_uninit + + let new_v = might_panic(taken_v); + std::mem::forget(mem::replace(&mut v, new_v)); + } + + unsafe { + let taken_v = std::ptr::read(&mut v); + //~^ mem_replace_with_uninit + + let new_v = might_panic(taken_v); + std::mem::forget(mem::replace(&mut v, new_v)); + } + + // this is silly but OK, because usize is a primitive type + let mut u: usize = 42; + let uref = &mut u; + let taken_u = unsafe { mem::replace(uref, mem::zeroed()) }; + *uref = taken_u + 1; + + // this is still not OK, because uninit + let taken_u = unsafe { std::ptr::read(uref) }; + //~^ mem_replace_with_uninit + + *uref = taken_u + 1; +} diff --git a/tests/ui/repl_uninit.rs b/tests/ui/mem_replace_with_uninit.rs similarity index 78% rename from tests/ui/repl_uninit.rs rename to tests/ui/mem_replace_with_uninit.rs index e9469d4c5e2f..0e6ede307f02 100644 --- a/tests/ui/repl_uninit.rs +++ b/tests/ui/mem_replace_with_uninit.rs @@ -1,6 +1,15 @@ -#![allow(deprecated, invalid_value, clippy::uninit_assumed_init)] #![warn(clippy::mem_replace_with_uninit)] -//@no-rustfix +#![allow( + // These get removed by the suggestion + deprecated, // for `std::mem::uninitialized` + invalid_value, + clippy::uninit_assumed_init, + + // Added because the suggestion is `std::ptr::read(&mut v)` + // (which might be considered a bug) + clippy::unnecessary_mut_passed, +)] + use std::mem; fn might_panic(x: X) -> X { @@ -27,14 +36,6 @@ fn main() { std::mem::forget(mem::replace(&mut v, new_v)); } - unsafe { - let taken_v = mem::replace(&mut v, mem::zeroed()); - //~^ mem_replace_with_uninit - - let new_v = might_panic(taken_v); - std::mem::forget(mem::replace(&mut v, new_v)); - } - // this is silly but OK, because usize is a primitive type let mut u: usize = 42; let uref = &mut u; diff --git a/tests/ui/repl_uninit.stderr b/tests/ui/mem_replace_with_uninit.stderr similarity index 55% rename from tests/ui/repl_uninit.stderr rename to tests/ui/mem_replace_with_uninit.stderr index 08b0b265942d..b5616ab72226 100644 --- a/tests/ui/repl_uninit.stderr +++ b/tests/ui/mem_replace_with_uninit.stderr @@ -1,31 +1,23 @@ error: replacing with `mem::uninitialized()` - --> tests/ui/repl_uninit.rs:15:23 + --> tests/ui/mem_replace_with_uninit.rs:24:23 | LL | let taken_v = mem::replace(&mut v, mem::uninitialized()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::ptr::read` instead: `std::ptr::read(&mut v)` | = note: `-D clippy::mem-replace-with-uninit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]` error: replacing with `mem::MaybeUninit::uninit().assume_init()` - --> tests/ui/repl_uninit.rs:23:23 + --> tests/ui/mem_replace_with_uninit.rs:32:23 | LL | let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` - -error: replacing with `mem::zeroed()` - --> tests/ui/repl_uninit.rs:31:23 - | -LL | let taken_v = mem::replace(&mut v, mem::zeroed()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider using a default value or the `take_mut` crate instead + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::ptr::read` instead: `std::ptr::read(&mut v)` error: replacing with `mem::uninitialized()` - --> tests/ui/repl_uninit.rs:45:28 + --> tests/ui/mem_replace_with_uninit.rs:46:28 | LL | let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `std::ptr::read` instead: `std::ptr::read(uref)` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/mem_replace_with_uninit_unfixable.rs b/tests/ui/mem_replace_with_uninit_unfixable.rs new file mode 100644 index 000000000000..7abb7f2c5dc3 --- /dev/null +++ b/tests/ui/mem_replace_with_uninit_unfixable.rs @@ -0,0 +1,22 @@ +// The lint does not offer a suggestion for the `zeroed` case +//@ no-rustfix +#![warn(clippy::mem_replace_with_uninit)] +#![expect(invalid_value)] + +use std::mem; + +fn might_panic(x: X) -> X { + // in practice this would be a possibly-panicky operation + x +} + +fn main() { + let mut v = vec![0i32; 4]; + unsafe { + let taken_v = mem::replace(&mut v, mem::zeroed()); + //~^ mem_replace_with_uninit + + let new_v = might_panic(taken_v); + std::mem::forget(mem::replace(&mut v, new_v)); + } +} diff --git a/tests/ui/mem_replace_with_uninit_unfixable.stderr b/tests/ui/mem_replace_with_uninit_unfixable.stderr new file mode 100644 index 000000000000..166d9fdd2ea8 --- /dev/null +++ b/tests/ui/mem_replace_with_uninit_unfixable.stderr @@ -0,0 +1,12 @@ +error: replacing with `mem::zeroed()` + --> tests/ui/mem_replace_with_uninit_unfixable.rs:16:23 + | +LL | let taken_v = mem::replace(&mut v, mem::zeroed()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using a default value or the `take_mut` crate instead + = note: `-D clippy::mem-replace-with-uninit` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]` + +error: aborting due to 1 previous error +