From 688220582c94d129a2311ebd48ca69f28f4d8d07 Mon Sep 17 00:00:00 2001 From: moonie <67006455+Kim-Dewelski@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:49:04 +0200 Subject: [PATCH 1/4] added core::mem::reshape --- library/core/src/mem/mod.rs | 12 ++++++++++++ library/core/tests/mem.rs | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 414262fcf5ab1..693e4968ae114 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -874,6 +874,18 @@ pub const fn replace(dest: &mut T, src: T) -> T { } } +#[inline] +#[unstable(feature = "mem_reshape", issue = "none")] +pub fn reshape(dest: &mut T, f: impl FnOnce(T) -> T) { + // SAFETY: We read from `dest` but directly write to it afterwards, + // such that the old value is not duplicated. Nothing is dropped and + // nothing here can panic. + unsafe { + let result = ptr::read(dest); + ptr::write(dest, f(result)); + } +} + /// Disposes of a value. /// /// This does so by calling the argument's implementation of [`Drop`][drop]. diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index f3b4387f6a898..ede4f4e971861 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -110,6 +110,17 @@ fn test_replace() { assert!(y.is_some()); } +#[test] +fn test_reshape() { + let mut x = Some("test".to_string()); + reshape(&mut x, |x| None); + assert!(x.is_none()); + + let mut y = "test".to_string(); + reshape(&mut y, |y| y + "test"); + assert_eq!(y, "testtest"); +} + #[test] fn test_transmute_copy() { assert_eq!(1, unsafe { transmute_copy(&1) }); From ef3048ee20bdd896d8f0cce91a8a6888115481a3 Mon Sep 17 00:00:00 2001 From: moonie <67006455+Kim-Dewelski@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:59:57 +0200 Subject: [PATCH 2/4] added simple documentation --- library/core/src/mem/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 693e4968ae114..f38eb0073aad5 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -874,6 +874,26 @@ pub const fn replace(dest: &mut T, src: T) -> T { } } +/// Replaces the value in `dest` by the value returned by `f`. +/// +/// `f` receives the current referenced value of `dest` as its argument. +/// +/// * If you want to replace the values of two variables, see [`swap`]. +/// * If you want to replace with a default value, see [`take`]. +/// * If you want replace without the function, see [`replace`]. +/// +/// # Examples +/// +/// A simple example: +/// +/// ``` +/// use std::mem; +/// +/// let mut v: Vec = vec![1, 2]; +/// +/// mem::replace(&mut v, |mut v| { v.push(3); v }); +/// assert_eq!(vec![1, 2, 3], v); +/// ``` #[inline] #[unstable(feature = "mem_reshape", issue = "none")] pub fn reshape(dest: &mut T, f: impl FnOnce(T) -> T) { From d1169fde5ba9197ce3cbec795ea0e968ce71e516 Mon Sep 17 00:00:00 2001 From: moonie <67006455+Kim-Dewelski@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:00:48 +0200 Subject: [PATCH 3/4] added tracking issue --- library/core/src/mem/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index f38eb0073aad5..67b6c79b7e32f 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -895,7 +895,7 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// assert_eq!(vec![1, 2, 3], v); /// ``` #[inline] -#[unstable(feature = "mem_reshape", issue = "none")] +#[unstable(feature = "mem_reshape", issue = "130848")] pub fn reshape(dest: &mut T, f: impl FnOnce(T) -> T) { // SAFETY: We read from `dest` but directly write to it afterwards, // such that the old value is not duplicated. Nothing is dropped and From 9bd7cbecc66b521dd88765635f967e770162fd35 Mon Sep 17 00:00:00 2001 From: moonie <67006455+Kim-Dewelski@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:10:48 +0200 Subject: [PATCH 4/4] removed unused variable in test --- library/core/tests/mem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index ede4f4e971861..5e2bdfda3700e 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -113,7 +113,7 @@ fn test_replace() { #[test] fn test_reshape() { let mut x = Some("test".to_string()); - reshape(&mut x, |x| None); + reshape(&mut x, |_| None); assert!(x.is_none()); let mut y = "test".to_string();