Skip to content

Commit

Permalink
Rollup merge of #77074 - lcnr:array-from-ref, r=SimonSapin
Browse files Browse the repository at this point in the history
add array::from_ref

mirrors the methods in `std::slice` with the same name.

I guess this method previously didn't exist as there was close to no reason to create an array of size `1`.
This will change due to const generics in the near future.
  • Loading branch information
jonas-schievink authored Sep 25, 2020
2 parents 862faea + 5b30161 commit 09b0bd6
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
14 changes: 14 additions & 0 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ mod iter;
#[unstable(feature = "array_value_iter", issue = "65798")]
pub use iter::IntoIter;

/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
#[unstable(feature = "array_from_ref", issue = "77101")]
pub fn from_ref<T>(s: &T) -> &[T; 1] {
// SAFETY: Converting `&T` to `&[T; 1]` is sound.
unsafe { &*(s as *const T).cast::<[T; 1]>() }
}

/// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
#[unstable(feature = "array_from_ref", issue = "77101")]
pub fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
// SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
unsafe { &mut *(s as *mut T).cast::<[T; 1]>() }
}

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
Expand Down
13 changes: 3 additions & 10 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Free functions to create `&[T]` and `&mut [T]`.
use crate::array;
use crate::intrinsics::is_aligned_and_not_null;
use crate::mem;
use crate::ptr;
Expand Down Expand Up @@ -140,19 +141,11 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T]
/// Converts a reference to T into a slice of length 1 (without copying).
#[stable(feature = "from_ref", since = "1.28.0")]
pub fn from_ref<T>(s: &T) -> &[T] {
// SAFETY: a reference is guaranteed to be valid for reads. The returned
// reference cannot be mutated as it is an immutable reference.
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
// Thus the call to `from_raw_parts` is safe.
unsafe { from_raw_parts(s, 1) }
array::from_ref(s)
}

/// Converts a reference to T into a slice of length 1 (without copying).
#[stable(feature = "from_ref", since = "1.28.0")]
pub fn from_mut<T>(s: &mut T) -> &mut [T] {
// SAFETY: a mutable reference is guaranteed to be valid for writes.
// The reference cannot be accessed by another pointer as it is an mutable reference.
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
// Thus the call to `from_raw_parts_mut` is safe.
unsafe { from_raw_parts_mut(s, 1) }
array::from_mut(s)
}
17 changes: 16 additions & 1 deletion library/core/tests/array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::array::{FixedSizeArray, IntoIter};
use core::array::{self, FixedSizeArray, IntoIter};
use core::convert::TryFrom;

#[test]
Expand All @@ -19,6 +19,21 @@ fn fixed_size_array() {
assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_zero_sized).len(), 0);
}

#[test]
fn array_from_ref() {
let value: String = "Hello World!".into();
let arr: &[String; 1] = array::from_ref(&value);
assert_eq!(&[value.clone()], arr);
}

#[test]
fn array_from_mut() {
let mut value: String = "Hello World".into();
let arr: &mut [String; 1] = array::from_mut(&mut value);
arr[0].push_str("!");
assert_eq!(&value, "Hello World!");
}

#[test]
fn array_try_from() {
macro_rules! test {
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![feature(alloc_layout_extra)]
#![feature(array_chunks)]
#![feature(array_from_ref)]
#![feature(array_methods)]
#![feature(array_map)]
#![feature(array_windows)]
Expand Down

0 comments on commit 09b0bd6

Please sign in to comment.