From 9fe9041cc8eddaed402d17aa4facb2ce8f222e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 22 Oct 2024 21:14:22 +0200 Subject: [PATCH] Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>` --- library/alloc/src/boxed/convert.rs | 45 ++++++++++++++++++++++++++++++ library/alloc/src/ffi/c_str.rs | 31 ++++++++++++++++++++ library/alloc/src/rc.rs | 40 ++++++++++++++++++++++++++ library/alloc/src/sync.rs | 40 ++++++++++++++++++++++++++ library/std/src/ffi/os_str.rs | 27 ++++++++++++++++++ library/std/src/path.rs | 28 +++++++++++++++++++ 6 files changed, 211 insertions(+) diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index 19a583ca546..4430fff6677 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -109,6 +109,29 @@ fn from(slice: &[T]) -> Box<[T]> { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut [T]> for Box<[T]> { + /// Converts a `&mut [T]` into a `Box<[T]>` + /// + /// This conversion allocates on the heap + /// and performs a copy of `slice` and its contents. + /// + /// # Examples + /// ```rust + /// // create a &mut [u8] which will be used to create a Box<[u8]> + /// let mut array = [104, 101, 108, 108, 111]; + /// let slice: &mut [u8] = &mut array; + /// let boxed_slice: Box<[u8]> = Box::from(slice); + /// + /// println!("{boxed_slice:?}"); + /// ``` + #[inline] + fn from(slice: &mut [T]) -> Box<[T]> { + Self::from(&*slice) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_cow", since = "1.45.0")] impl From> for Box<[T]> { @@ -147,6 +170,28 @@ fn from(s: &str) -> Box { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut str> for Box { + /// Converts a `&mut str` into a `Box` + /// + /// This conversion allocates on the heap + /// and performs a copy of `s`. + /// + /// # Examples + /// + /// ```rust + /// let mut original = String::from("hello"); + /// let original: &mut str = &mut original; + /// let boxed: Box = Box::from(original); + /// println!("{boxed}"); + /// ``` + #[inline] + fn from(s: &mut str) -> Box { + Self::from(&*s) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_cow", since = "1.45.0")] impl From> for Box { diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index d7e99f4a1a6..d91682b796e 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -772,6 +772,16 @@ fn from(s: &CStr) -> Box { } } +#[cfg(not(test))] +#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut CStr> for Box { + /// Converts a `&mut CStr` into a `Box`, + /// by copying the contents into a newly allocated [`Box`]. + fn from(s: &mut CStr) -> Box { + Self::from(&*s) + } +} + #[stable(feature = "box_from_cow", since = "1.45.0")] impl From> for Box { /// Converts a `Cow<'a, CStr>` into a `Box`, @@ -910,6 +920,17 @@ fn from(s: &CStr) -> Arc { } } +#[cfg(target_has_atomic = "ptr")] +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut CStr> for Arc { + /// Converts a `&mut CStr` into a `Arc`, + /// by copying the contents into a newly allocated [`Arc`]. + #[inline] + fn from(s: &mut CStr) -> Arc { + Arc::from(&*s) + } +} + #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { /// Converts a [`CString`] into an [Rc]<[CStr]> by moving the [`CString`] @@ -932,6 +953,16 @@ fn from(s: &CStr) -> Rc { } } +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut CStr> for Rc { + /// Converts a `&mut CStr` into a `Rc`, + /// by copying the contents into a newly allocated [`Rc`]. + #[inline] + fn from(s: &mut CStr) -> Rc { + Rc::from(&*s) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Rc { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 9fdd51ce331..3128716497b 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2651,6 +2651,26 @@ fn from(v: &[T]) -> Rc<[T]> { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut [T]> for Rc<[T]> { + /// Allocates a reference-counted slice and fills it by cloning `v`'s items. + /// + /// # Example + /// + /// ``` + /// # use std::rc::Rc; + /// let mut original = [1, 2, 3]; + /// let original: &mut [i32] = &mut original; + /// let shared: Rc<[i32]> = Rc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: &mut [T]) -> Rc<[T]> { + Rc::from(&*v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From<&str> for Rc { @@ -2670,6 +2690,26 @@ fn from(v: &str) -> Rc { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut str> for Rc { + /// Allocates a reference-counted string slice and copies `v` into it. + /// + /// # Example + /// + /// ``` + /// # use std::rc::Rc; + /// let mut original = String::from("statue"); + /// let original: &mut str = &mut original; + /// let shared: Rc = Rc::from(original); + /// assert_eq!("statue", &shared[..]); + /// ``` + #[inline] + fn from(v: &mut str) -> Rc { + Rc::from(&*v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From for Rc { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 15a1b0f2834..3ace7d1fa03 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3612,6 +3612,26 @@ fn from(v: &[T]) -> Arc<[T]> { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut [T]> for Arc<[T]> { + /// Allocates a reference-counted slice and fills it by cloning `v`'s items. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let mut original = [1, 2, 3]; + /// let original: &mut [i32] = &mut original; + /// let shared: Arc<[i32]> = Arc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: &mut [T]) -> Arc<[T]> { + Arc::from(&*v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From<&str> for Arc { @@ -3631,6 +3651,26 @@ fn from(v: &str) -> Arc { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut str> for Arc { + /// Allocates a reference-counted `str` and copies `v` into it. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let mut original = String::from("eggplant"); + /// let original: &mut str = &mut original; + /// let shared: Arc = Arc::from(original); + /// assert_eq!("eggplant", &shared[..]); + /// ``` + #[inline] + fn from(v: &mut str) -> Arc { + Arc::from(&*v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From for Arc { diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 2243f100643..b19d482feaa 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1225,6 +1225,15 @@ fn from(s: &OsStr) -> Box { } } +#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut OsStr> for Box { + /// Copies the string into a newly allocated [Box]<[OsStr]>. + #[inline] + fn from(s: &mut OsStr) -> Box { + Self::from(&*s) + } +} + #[stable(feature = "box_from_cow", since = "1.45.0")] impl From> for Box { /// Converts a `Cow<'a, OsStr>` into a [Box]<[OsStr]>, @@ -1296,6 +1305,15 @@ fn from(s: &OsStr) -> Arc { } } +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut OsStr> for Arc { + /// Copies the string into a newly allocated [Arc]<[OsStr]>. + #[inline] + fn from(s: &mut OsStr) -> Arc { + Arc::from(&*s) + } +} + #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { /// Converts an [`OsString`] into an [Rc]<[OsStr]> by moving the [`OsString`] @@ -1317,6 +1335,15 @@ fn from(s: &OsStr) -> Rc { } } +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut OsStr> for Rc { + /// Copies the string into a newly allocated [Rc]<[OsStr]>. + #[inline] + fn from(s: &mut OsStr) -> Rc { + Rc::from(&*s) + } +} + #[stable(feature = "cow_from_osstr", since = "1.28.0")] impl<'a> From for Cow<'a, OsStr> { /// Moves the string into a [`Cow::Owned`]. diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 62125f885b2..5662a44d832 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1762,6 +1762,16 @@ fn from(path: &Path) -> Box { } } +#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut Path> for Box { + /// Creates a boxed [`Path`] from a reference. + /// + /// This will allocate and clone `path` to it. + fn from(path: &mut Path) -> Box { + Self::from(&*path) + } +} + #[stable(feature = "box_from_cow", since = "1.45.0")] impl From> for Box { /// Creates a boxed [`Path`] from a clone-on-write pointer. @@ -1990,6 +2000,15 @@ fn from(s: &Path) -> Arc { } } +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut Path> for Arc { + /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer. + #[inline] + fn from(s: &mut Path) -> Arc { + Arc::from(&*s) + } +} + #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { /// Converts a [`PathBuf`] into an [Rc]<[Path]> by moving the [`PathBuf`] data into @@ -2011,6 +2030,15 @@ fn from(s: &Path) -> Rc { } } +#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut Path> for Rc { + /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer. + #[inline] + fn from(s: &mut Path) -> Rc { + Rc::from(&*s) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for Path { type Owned = PathBuf;