Skip to content

Commit 4023ee8

Browse files
authored
Unrolled build for rust-lang#133512
Rollup merge of rust-lang#133512 - bjoernager:slice-as-array, r=Amanieu Add `as_array` and `as_mut_array` conversion methods to slices. Tracking issue: rust-lang#133508 This PR unstably implements the `as_array` and `as_mut_array` converters to `[T]`, `*const [T]`, and `*mut [T]`.
2 parents eddb717 + 4b8ca28 commit 4023ee8

File tree

5 files changed

+75
-16
lines changed

5 files changed

+75
-16
lines changed

library/core/src/array/mod.rs

+4-16
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
214214
}
215215
}
216216

217-
/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. Succeeds if
218-
/// `slice.len() == N`.
217+
/// Tries to create an array `[T; N]` by copying from a slice `&[T]`.
218+
/// Succeeds if `slice.len() == N`.
219219
///
220220
/// ```
221221
/// let bytes: [u8; 3] = [1, 0, 2];
@@ -282,13 +282,7 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
282282

283283
#[inline]
284284
fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
285-
if slice.len() == N {
286-
let ptr = slice.as_ptr() as *const [T; N];
287-
// SAFETY: ok because we just checked that the length fits
288-
unsafe { Ok(&*ptr) }
289-
} else {
290-
Err(TryFromSliceError(()))
291-
}
285+
slice.as_array().ok_or(TryFromSliceError(()))
292286
}
293287
}
294288

@@ -310,13 +304,7 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
310304

311305
#[inline]
312306
fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
313-
if slice.len() == N {
314-
let ptr = slice.as_mut_ptr() as *mut [T; N];
315-
// SAFETY: ok because we just checked that the length fits
316-
unsafe { Ok(&mut *ptr) }
317-
} else {
318-
Err(TryFromSliceError(()))
319-
}
307+
slice.as_mut_array().ok_or(TryFromSliceError(()))
320308
}
321309
}
322310

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
#![feature(ptr_alignment_type)]
145145
#![feature(ptr_metadata)]
146146
#![feature(set_ptr_value)]
147+
#![feature(slice_as_array)]
147148
#![feature(slice_as_chunks)]
148149
#![feature(slice_ptr_get)]
149150
#![feature(str_internals)]

library/core/src/ptr/const_ptr.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,22 @@ impl<T> *const [T] {
15261526
self as *const T
15271527
}
15281528

1529+
/// Gets a raw pointer to the underlying array.
1530+
///
1531+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1532+
#[unstable(feature = "slice_as_array", issue = "133508")]
1533+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
1534+
#[inline]
1535+
#[must_use]
1536+
pub const fn as_array<const N: usize>(self) -> Option<*const [T; N]> {
1537+
if self.len() == N {
1538+
let me = self.as_ptr() as *const [T; N];
1539+
Some(me)
1540+
} else {
1541+
None
1542+
}
1543+
}
1544+
15291545
/// Returns a raw pointer to an element or subslice, without doing bounds
15301546
/// checking.
15311547
///

library/core/src/ptr/mut_ptr.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,22 @@ impl<T> *mut [T] {
17601760
self.len() == 0
17611761
}
17621762

1763+
/// Gets a raw, mutable pointer to the underlying array.
1764+
///
1765+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1766+
#[unstable(feature = "slice_as_array", issue = "133508")]
1767+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
1768+
#[inline]
1769+
#[must_use]
1770+
pub const fn as_mut_array<const N: usize>(self) -> Option<*mut [T; N]> {
1771+
if self.len() == N {
1772+
let me = self.as_mut_ptr() as *mut [T; N];
1773+
Some(me)
1774+
} else {
1775+
None
1776+
}
1777+
}
1778+
17631779
/// Divides one mutable raw slice into two at an index.
17641780
///
17651781
/// The first will contain all indices from `[0, mid)` (excluding

library/core/src/slice/mod.rs

+38
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,44 @@ impl<T> [T] {
855855
start..end
856856
}
857857

858+
/// Gets a reference to the underlying array.
859+
///
860+
/// If `N` is not exactly equal to slice's the length of `self`, then this method returns `None`.
861+
#[unstable(feature = "slice_as_array", issue = "133508")]
862+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
863+
#[inline]
864+
#[must_use]
865+
pub const fn as_array<const N: usize>(&self) -> Option<&[T; N]> {
866+
if self.len() == N {
867+
let ptr = self.as_ptr() as *const [T; N];
868+
869+
// SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.
870+
let me = unsafe { &*ptr };
871+
Some(me)
872+
} else {
873+
None
874+
}
875+
}
876+
877+
/// Gets a mutable reference to the slice's underlying array.
878+
///
879+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
880+
#[unstable(feature = "slice_as_array", issue = "133508")]
881+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
882+
#[inline]
883+
#[must_use]
884+
pub const fn as_mut_array<const N: usize>(&mut self) -> Option<&mut [T; N]> {
885+
if self.len() == N {
886+
let ptr = self.as_mut_ptr() as *mut [T; N];
887+
888+
// SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.
889+
let me = unsafe { &mut *ptr };
890+
Some(me)
891+
} else {
892+
None
893+
}
894+
}
895+
858896
/// Swaps two elements in the slice.
859897
///
860898
/// If `a` equals to `b`, it's guaranteed that elements won't change value.

0 commit comments

Comments
 (0)