From 7c4ca59f4b10d20f0f3e902f847641311abb093c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 17 Apr 2020 11:36:56 -0700 Subject: [PATCH 1/3] Lint must_use on mem::replace This adds a hint on `mem::replace`, "if you don't need the old value, you can just assign the new value directly". This is in similar spirit to the `must_use` on `ManuallyDrop::take`. --- src/libcore/mem/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 07f7d28bb7546..3fa2b7a2d042c 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -808,6 +808,7 @@ pub fn take(dest: &mut T) -> T { /// [`Clone`]: ../../std/clone/trait.Clone.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "if you don't need the old value, you can just assign the new value directly"] pub fn replace(dest: &mut T, mut src: T) -> T { swap(dest, &mut src); src From ccecae5fdd27fa7695fd45c98ff755029a750eb7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 17 Apr 2020 13:59:14 -0700 Subject: [PATCH 2/3] Fix unused results from mem::replace --- src/libcore/marker.rs | 1 + src/librustc_parse/parser/expr.rs | 7 +++---- src/librustc_parse/parser/generics.rs | 2 +- src/librustc_parse/parser/item.rs | 2 +- src/librustc_parse/parser/stmt.rs | 6 +++--- src/librustc_resolve/late/lifetimes.rs | 4 ++-- src/libstd/thread/local.rs | 2 +- src/test/ui/imports/import-in-block.rs | 2 +- src/test/ui/issues/issue-23611-enum-swap-in-drop.rs | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 35bceaa25c36e..549933ceeb645 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -709,6 +709,7 @@ unsafe impl Freeze for &mut T {} /// So this, for example, can only be done on types implementing `Unpin`: /// /// ```rust +/// # #![allow(unused_must_use)] /// use std::mem; /// use std::pin::Pin; /// diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 4e3c5fa63de2c..a04a1b220fee1 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -547,8 +547,7 @@ impl<'a> Parser<'a> { // Rewind to before attempting to parse the type with generics, to recover // from situations like `x as usize < y` in which we first tried to parse // `usize < y` as a type with generic arguments. - let parser_snapshot_after_type = self.clone(); - mem::replace(self, parser_snapshot_before_type); + let parser_snapshot_after_type = mem::replace(self, parser_snapshot_before_type); match self.parse_path(PathStyle::Expr) { Ok(path) => { @@ -560,7 +559,7 @@ impl<'a> Parser<'a> { // example because `parse_ty_no_plus` returns `Err` on keywords, // but `parse_path` returns `Ok` on them due to error recovery. // Return original error and parser state. - mem::replace(self, parser_snapshot_after_type); + *self = parser_snapshot_after_type; return Err(type_err); } }; @@ -601,7 +600,7 @@ impl<'a> Parser<'a> { Err(mut path_err) => { // Couldn't parse as a path, return original error and parser state. path_err.cancel(); - mem::replace(self, parser_snapshot_after_type); + *self = parser_snapshot_after_type; return Err(type_err); } } diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 3442c5081c18f..85e0414369a2a 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -105,7 +105,7 @@ impl<'a> Parser<'a> { } Err(mut err) => { err.cancel(); - std::mem::replace(self, snapshot); + *self = snapshot; break; } } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 798eb85f36f36..0496b0f334838 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1650,7 +1650,7 @@ impl<'a> Parser<'a> { // Recover from attempting to parse the argument as a type without pattern. Err(mut err) => { err.cancel(); - mem::replace(self, parser_snapshot_before_ty); + *self = parser_snapshot_before_ty; self.recover_arg_parse()? } } diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index b3764d2d47be1..e5d0ab247aa46 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -163,8 +163,8 @@ impl<'a> Parser<'a> { Ok(ty) => (None, Some(ty)), Err(mut err) => { // Rewind to before attempting to parse the type and continue parsing. - let parser_snapshot_after_type = self.clone(); - mem::replace(self, parser_snapshot_before_type); + let parser_snapshot_after_type = + mem::replace(self, parser_snapshot_before_type); if let Ok(snip) = self.span_to_snippet(pat.span) { err.span_label(pat.span, format!("while parsing the type for `{}`", snip)); } @@ -201,7 +201,7 @@ impl<'a> Parser<'a> { // Couldn't parse the type nor the initializer, only raise the type error and // return to the parser state before parsing the type as the initializer. // let x: ; - mem::replace(self, snapshot); + *self = snapshot; return Err(ty_err); } (Err(err), None) => { diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 5b6a50f88db45..34725d2d5234b 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -26,7 +26,7 @@ use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use std::borrow::Cow; use std::cell::Cell; -use std::mem::{replace, take}; +use std::mem::take; use log::debug; @@ -371,7 +371,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.with(Scope::Body { id: body.id(), s: self.scope }, |_, this| { this.visit_body(body); }); - replace(&mut self.labels_in_fn, saved); + self.labels_in_fn = saved; } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 29e99c0afd27f..094c468a6770e 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -301,7 +301,7 @@ mod lazy { // value (an aliasing violation). To avoid setting the "I'm running a // destructor" flag we just use `mem::replace` which should sequence the // operations a little differently and make this safe to call. - mem::replace(&mut *ptr, Some(value)); + let _ = mem::replace(&mut *ptr, Some(value)); // After storing `Some` we want to get a reference to the contents of // what we just stored. While we could use `unwrap` here and it should diff --git a/src/test/ui/imports/import-in-block.rs b/src/test/ui/imports/import-in-block.rs index c0ba6220b5443..19703904ece91 100644 --- a/src/test/ui/imports/import-in-block.rs +++ b/src/test/ui/imports/import-in-block.rs @@ -4,7 +4,7 @@ pub fn main() { use std::mem::replace; let mut x = 5; - replace(&mut x, 6); + let _ = replace(&mut x, 6); { use std::mem::*; let mut y = 6; diff --git a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs index 6ef7fd42ec6d0..8e4319a8b18ec 100644 --- a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs +++ b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs @@ -154,7 +154,7 @@ impl<'a> Drop for E<'a> { }; if do_drop { - mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true)); + let _ = mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true)); } } } From 7fca9f809da1c65afa09e7d6e35b9599f87f03d3 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sun, 19 Apr 2020 18:15:06 -0700 Subject: [PATCH 3/3] allow(unused_must_use) in issue-23611-enum-swap-in-drop.rs --- src/test/ui/issues/issue-23611-enum-swap-in-drop.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs index 8e4319a8b18ec..403cf970bcb0a 100644 --- a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs +++ b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs @@ -153,8 +153,9 @@ impl<'a> Drop for E<'a> { } }; + #[allow(unused_must_use)] if do_drop { - let _ = mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true)); + mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true)); } } }