Skip to content

Commit

Permalink
Rollup merge of #129329 - eduardosm:rc-from-mut-slice, r=dtolnay
Browse files Browse the repository at this point in the history
Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>`

ACP: rust-lang/libs-team#424

New API:

```rust
impl<T: Clone> From<&mut [T]> for Box<[T]>
impl From<&mut str> for Box<str>
impl From<&mut CStr> for Box<CStr>
impl From<&mut OsStr> for Box<OsStr>
impl From<&mut Path> for Box<Path>

impl<T: Clone> From<&mut [T]> for Rc<[T]>
impl From<&mut str> for Rc<str>
impl From<&mut CStr> for Rc<CStr>
impl From<&mut OsStr> for Rc<OsStr>
impl From<&mut Path> for Rc<Path>

impl<T: Clone> From<&mut [T]> for Arc<[T]>
impl From<&mut str> for Arc<str>
impl From<&mut CStr> for Arc<CStr>
impl From<&mut OsStr> for Arc<OsStr>
impl From<&mut Path> for Arc<Path>
```

Since they are trait implementations, I think these are insta-stable.

As mentioned in rust-lang/libs-team#424 (comment), a crater run might be needed.
  • Loading branch information
matthiaskrgr authored Nov 3, 2024
2 parents db034ce + 9fe9041 commit 957f6c3
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 0 deletions.
45 changes: 45 additions & 0 deletions library/alloc/src/boxed/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,29 @@ impl<T: Clone> From<&[T]> for Box<[T]> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl<T: Clone> 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<T: Clone> From<Cow<'_, [T]>> for Box<[T]> {
Expand Down Expand Up @@ -147,6 +170,28 @@ impl From<&str> for Box<str> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut str> for Box<str> {
/// Converts a `&mut str` into a `Box<str>`
///
/// 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<str> = Box::from(original);
/// println!("{boxed}");
/// ```
#[inline]
fn from(s: &mut str) -> Box<str> {
Self::from(&*s)
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, str>> for Box<str> {
Expand Down
31 changes: 31 additions & 0 deletions library/alloc/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,16 @@ impl From<&CStr> for Box<CStr> {
}
}

#[cfg(not(test))]
#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut CStr> for Box<CStr> {
/// Converts a `&mut CStr` into a `Box<CStr>`,
/// by copying the contents into a newly allocated [`Box`].
fn from(s: &mut CStr) -> Box<CStr> {
Self::from(&*s)
}
}

#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, CStr>> for Box<CStr> {
/// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
Expand Down Expand Up @@ -910,6 +920,17 @@ impl From<&CStr> for Arc<CStr> {
}
}

#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut CStr> for Arc<CStr> {
/// Converts a `&mut CStr` into a `Arc<CStr>`,
/// by copying the contents into a newly allocated [`Arc`].
#[inline]
fn from(s: &mut CStr) -> Arc<CStr> {
Arc::from(&*s)
}
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<CString> for Rc<CStr> {
/// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> by moving the [`CString`]
Expand All @@ -932,6 +953,16 @@ impl From<&CStr> for Rc<CStr> {
}
}

#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut CStr> for Rc<CStr> {
/// Converts a `&mut CStr` into a `Rc<CStr>`,
/// by copying the contents into a newly allocated [`Rc`].
#[inline]
fn from(s: &mut CStr) -> Rc<CStr> {
Rc::from(&*s)
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "more_rc_default_impls", since = "1.80.0")]
impl Default for Rc<CStr> {
Expand Down
40 changes: 40 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2657,6 +2657,26 @@ impl<T: Clone> From<&[T]> for Rc<[T]> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl<T: Clone> 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<str> {
Expand All @@ -2676,6 +2696,26 @@ impl From<&str> for Rc<str> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut str> for Rc<str> {
/// 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<str> = Rc::from(original);
/// assert_eq!("statue", &shared[..]);
/// ```
#[inline]
fn from(v: &mut str) -> Rc<str> {
Rc::from(&*v)
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<String> for Rc<str> {
Expand Down
40 changes: 40 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3614,6 +3614,26 @@ impl<T: Clone> From<&[T]> for Arc<[T]> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl<T: Clone> 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<str> {
Expand All @@ -3633,6 +3653,26 @@ impl From<&str> for Arc<str> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut str> for Arc<str> {
/// 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<str> = Arc::from(original);
/// assert_eq!("eggplant", &shared[..]);
/// ```
#[inline]
fn from(v: &mut str) -> Arc<str> {
Arc::from(&*v)
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<String> for Arc<str> {
Expand Down
27 changes: 27 additions & 0 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,15 @@ impl From<&OsStr> for Box<OsStr> {
}
}

#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut OsStr> for Box<OsStr> {
/// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &mut OsStr) -> Box<OsStr> {
Self::from(&*s)
}
}

#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, OsStr>> for Box<OsStr> {
/// Converts a `Cow<'a, OsStr>` into a <code>[Box]&lt;[OsStr]&gt;</code>,
Expand Down Expand Up @@ -1296,6 +1305,15 @@ impl From<&OsStr> for Arc<OsStr> {
}
}

#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut OsStr> for Arc<OsStr> {
/// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &mut OsStr) -> Arc<OsStr> {
Arc::from(&*s)
}
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<OsString> for Rc<OsStr> {
/// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> by moving the [`OsString`]
Expand All @@ -1317,6 +1335,15 @@ impl From<&OsStr> for Rc<OsStr> {
}
}

#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut OsStr> for Rc<OsStr> {
/// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
#[inline]
fn from(s: &mut OsStr) -> Rc<OsStr> {
Rc::from(&*s)
}
}

#[stable(feature = "cow_from_osstr", since = "1.28.0")]
impl<'a> From<OsString> for Cow<'a, OsStr> {
/// Moves the string into a [`Cow::Owned`].
Expand Down
28 changes: 28 additions & 0 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,16 @@ impl From<&Path> for Box<Path> {
}
}

#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut Path> for Box<Path> {
/// Creates a boxed [`Path`] from a reference.
///
/// This will allocate and clone `path` to it.
fn from(path: &mut Path) -> Box<Path> {
Self::from(&*path)
}
}

#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, Path>> for Box<Path> {
/// Creates a boxed [`Path`] from a clone-on-write pointer.
Expand Down Expand Up @@ -1990,6 +2000,15 @@ impl From<&Path> for Arc<Path> {
}
}

#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut Path> for Arc<Path> {
/// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer.
#[inline]
fn from(s: &mut Path) -> Arc<Path> {
Arc::from(&*s)
}
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<PathBuf> for Rc<Path> {
/// Converts a [`PathBuf`] into an <code>[Rc]<[Path]></code> by moving the [`PathBuf`] data into
Expand All @@ -2011,6 +2030,15 @@ impl From<&Path> for Rc<Path> {
}
}

#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")]
impl From<&mut Path> for Rc<Path> {
/// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer.
#[inline]
fn from(s: &mut Path) -> Rc<Path> {
Rc::from(&*s)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for Path {
type Owned = PathBuf;
Expand Down

0 comments on commit 957f6c3

Please sign in to comment.