Rollup merge of #126711 - GKFX:const-option-as-slice, r=oli-obk

Make Option::as_[mut_]slice const

These two functions can both be made `const`. I have added them to the `const_option_ext` feature, #91930. I don't believe there is anything blocking stabilization of `as_slice`, but `as_mut_slice` contains mutable references so depends on `const_mut_refs`.
This commit is contained in:
Matthias Krüger 2024-06-20 14:07:03 +02:00 committed by GitHub
commit 7b91d11abb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 4 deletions

View File

@ -797,7 +797,8 @@ pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
#[inline]
#[must_use]
#[stable(feature = "option_as_slice", since = "1.75.0")]
pub fn as_slice(&self) -> &[T] {
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
pub const fn as_slice(&self) -> &[T] {
// SAFETY: When the `Option` is `Some`, we're using the actual pointer
// to the payload, with a length of 1, so this is equivalent to
// `slice::from_ref`, and thus is safe.
@ -811,7 +812,7 @@ pub fn as_slice(&self) -> &[T] {
unsafe {
slice::from_raw_parts(
(self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
usize::from(self.is_some()),
self.is_some() as usize,
)
}
}
@ -851,7 +852,8 @@ pub fn as_slice(&self) -> &[T] {
#[inline]
#[must_use]
#[stable(feature = "option_as_slice", since = "1.75.0")]
pub fn as_mut_slice(&mut self) -> &mut [T] {
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
pub const fn as_mut_slice(&mut self) -> &mut [T] {
// SAFETY: When the `Option` is `Some`, we're using the actual pointer
// to the payload, with a length of 1, so this is equivalent to
// `slice::from_mut`, and thus is safe.
@ -867,7 +869,7 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
unsafe {
slice::from_raw_parts_mut(
(self as *mut Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
usize::from(self.is_some()),
self.is_some() as usize,
)
}
}

View File

@ -574,4 +574,13 @@ fn as_slice() {
assert_eq!(Some(43).as_mut_slice(), &[43]);
assert_eq!(None::<i32>.as_slice(), &[]);
assert_eq!(None::<i32>.as_mut_slice(), &[]);
const A: &[u32] = Some(44).as_slice();
const B: &[u32] = None.as_slice();
const _: () = {
let [45] = Some(45).as_mut_slice() else { panic!() };
let []: &[u32] = None.as_mut_slice() else { panic!() };
};
assert_eq!(A, &[44]);
assert_eq!(B, &[]);
}