summaryrefslogtreecommitdiffstats
path: root/library/core/src/array
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /library/core/src/array
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/array')
-rw-r--r--library/core/src/array/ascii.rs47
-rw-r--r--library/core/src/array/iter.rs18
-rw-r--r--library/core/src/array/mod.rs35
3 files changed, 69 insertions, 31 deletions
diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs
new file mode 100644
index 000000000..3fea9a440
--- /dev/null
+++ b/library/core/src/array/ascii.rs
@@ -0,0 +1,47 @@
+use crate::ascii;
+
+#[cfg(not(test))]
+impl<const N: usize> [u8; N] {
+ /// Converts this array of bytes into a array of ASCII characters,
+ /// or returns `None` if any of the characters is non-ASCII.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(ascii_char)]
+ /// #![feature(const_option)]
+ ///
+ /// const HEX_DIGITS: [std::ascii::Char; 16] =
+ /// *b"0123456789abcdef".as_ascii().unwrap();
+ ///
+ /// assert_eq!(HEX_DIGITS[1].as_str(), "1");
+ /// assert_eq!(HEX_DIGITS[10].as_str(), "a");
+ /// ```
+ #[unstable(feature = "ascii_char", issue = "110998")]
+ #[must_use]
+ #[inline]
+ pub const fn as_ascii(&self) -> Option<&[ascii::Char; N]> {
+ if self.is_ascii() {
+ // SAFETY: Just checked that it's ASCII
+ Some(unsafe { self.as_ascii_unchecked() })
+ } else {
+ None
+ }
+ }
+
+ /// Converts this array of bytes into a array of ASCII characters,
+ /// without checking whether they're valid.
+ ///
+ /// # Safety
+ ///
+ /// Every byte in the array must be in `0..=127`, or else this is UB.
+ #[unstable(feature = "ascii_char", issue = "110998")]
+ #[must_use]
+ #[inline]
+ pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char; N] {
+ let byte_ptr: *const [u8; N] = self;
+ let ascii_ptr = byte_ptr as *const [ascii::Char; N];
+ // SAFETY: The caller promised all the bytes are ASCII
+ unsafe { &*ascii_ptr }
+ }
+}
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 73e2c2cfb..587877dff 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -3,8 +3,9 @@
use crate::num::NonZeroUsize;
use crate::{
fmt,
+ intrinsics::transmute_unchecked,
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
- mem::{self, MaybeUninit},
+ mem::MaybeUninit,
ops::{IndexRange, Range},
ptr,
};
@@ -63,18 +64,11 @@ impl<T, const N: usize> IntoIterator for [T; N] {
// an array of `T`.
//
// With that, this initialization satisfies the invariants.
-
- // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
- // works with const generics:
- // `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
//
- // Until then, we can use `mem::transmute_copy` to create a bitwise copy
- // as a different type, then forget `array` so that it is not dropped.
- unsafe {
- let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) };
- mem::forget(self);
- iter
- }
+ // FIXME: If normal `transmute` ever gets smart enough to allow this
+ // directly, use it instead of `transmute_unchecked`.
+ let data: [MaybeUninit<T>; N] = unsafe { transmute_unchecked(self) };
+ IntoIter { data, alive: IndexRange::zero_to(N) }
}
}
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 1643842d6..fec92320a 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -17,6 +17,7 @@ use crate::ops::{
};
use crate::slice::{Iter, IterMut};
+mod ascii;
mod drain;
mod equality;
mod iter;
@@ -148,8 +149,7 @@ impl Error for TryFromSliceError {
}
#[stable(feature = "try_from_slice_error", since = "1.36.0")]
-#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
-impl const From<Infallible> for TryFromSliceError {
+impl From<Infallible> for TryFromSliceError {
fn from(x: Infallible) -> TryFromSliceError {
match x {}
}
@@ -172,16 +172,14 @@ impl<T, const N: usize> AsMut<[T]> for [T; N] {
}
#[stable(feature = "array_borrow", since = "1.4.0")]
-#[rustc_const_unstable(feature = "const_borrow", issue = "91522")]
-impl<T, const N: usize> const Borrow<[T]> for [T; N] {
+impl<T, const N: usize> Borrow<[T]> for [T; N] {
fn borrow(&self) -> &[T] {
self
}
}
#[stable(feature = "array_borrow", since = "1.4.0")]
-#[rustc_const_unstable(feature = "const_borrow", issue = "91522")]
-impl<T, const N: usize> const BorrowMut<[T]> for [T; N] {
+impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
fn borrow_mut(&mut self) -> &mut [T] {
self
}
@@ -206,6 +204,7 @@ where
{
type Error = TryFromSliceError;
+ #[inline]
fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> {
<&Self>::try_from(slice).map(|r| *r)
}
@@ -230,6 +229,7 @@ where
{
type Error = TryFromSliceError;
+ #[inline]
fn try_from(slice: &mut [T]) -> Result<[T; N], TryFromSliceError> {
<Self>::try_from(&*slice)
}
@@ -251,7 +251,8 @@ where
impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
type Error = TryFromSliceError;
- fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
+ #[inline]
+ fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
if slice.len() == N {
let ptr = slice.as_ptr() as *const [T; N];
// SAFETY: ok because we just checked that the length fits
@@ -278,7 +279,8 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
type Error = TryFromSliceError;
- fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
+ #[inline]
+ fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
if slice.len() == N {
let ptr = slice.as_mut_ptr() as *mut [T; N];
// SAFETY: ok because we just checked that the length fits
@@ -293,7 +295,6 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
/// as required by the `Borrow` implementation.
///
/// ```
-/// #![feature(build_hasher_simple_hash_one)]
/// use std::hash::BuildHasher;
///
/// let b = std::collections::hash_map::RandomState::new();
@@ -336,10 +337,9 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
}
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
-#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
-impl<T, I, const N: usize> const Index<I> for [T; N]
+impl<T, I, const N: usize> Index<I> for [T; N]
where
- [T]: ~const Index<I>,
+ [T]: Index<I>,
{
type Output = <[T] as Index<I>>::Output;
@@ -350,10 +350,9 @@ where
}
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
-#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
-impl<T, I, const N: usize> const IndexMut<I> for [T; N]
+impl<T, I, const N: usize> IndexMut<I> for [T; N]
where
- [T]: ~const IndexMut<I>,
+ [T]: IndexMut<I>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
@@ -435,8 +434,7 @@ impl<T: Copy> SpecArrayClone for T {
macro_rules! array_impl_default {
{$n:expr, $t:ident $($ts:ident)*} => {
#[stable(since = "1.4.0", feature = "array_default")]
- #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
- impl<T> const Default for [T; $n] where T: ~const Default {
+ impl<T> Default for [T; $n] where T: Default {
fn default() -> [T; $n] {
[$t::default(), $($ts::default()),*]
}
@@ -445,8 +443,7 @@ macro_rules! array_impl_default {
};
{$n:expr,} => {
#[stable(since = "1.4.0", feature = "array_default")]
- #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
- impl<T> const Default for [T; $n] {
+ impl<T> Default for [T; $n] {
fn default() -> [T; $n] { [] }
}
};