Skip to content

Commit

Permalink
Rollup merge of rust-lang#126711 - GKFX:const-option-as-slice, r=oli-obk
Browse files Browse the repository at this point in the history
Make Option::as_[mut_]slice const

These two functions can both be made `const`. I have added them to the `const_option_ext` feature, rust-lang#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`.
  • Loading branch information
matthiaskrgr committed Jun 20, 2024
2 parents 9cbfbda + 35c65a8 commit 7b91d11
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
10 changes: 6 additions & 4 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,8 @@ impl<T> Option<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.
Expand All @@ -811,7 +812,7 @@ impl<T> Option<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,
)
}
}
Expand Down Expand Up @@ -851,7 +852,8 @@ impl<T> Option<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.
Expand All @@ -867,7 +869,7 @@ impl<T> Option<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,
)
}
}
Expand Down
9 changes: 9 additions & 0 deletions library/core/tests/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, &[]);
}

0 comments on commit 7b91d11

Please sign in to comment.