Skip to content

Commit f1c9c80

Browse files
authored
Rollup merge of rust-lang#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, 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`.
2 parents b6a3858 + 669d6fc commit f1c9c80

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

core/src/option.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,8 @@ impl<T> Option<T> {
797797
#[inline]
798798
#[must_use]
799799
#[stable(feature = "option_as_slice", since = "1.75.0")]
800-
pub fn as_slice(&self) -> &[T] {
800+
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
801+
pub const fn as_slice(&self) -> &[T] {
801802
// SAFETY: When the `Option` is `Some`, we're using the actual pointer
802803
// to the payload, with a length of 1, so this is equivalent to
803804
// `slice::from_ref`, and thus is safe.
@@ -811,7 +812,7 @@ impl<T> Option<T> {
811812
unsafe {
812813
slice::from_raw_parts(
813814
(self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
814-
usize::from(self.is_some()),
815+
self.is_some() as usize,
815816
)
816817
}
817818
}
@@ -851,7 +852,8 @@ impl<T> Option<T> {
851852
#[inline]
852853
#[must_use]
853854
#[stable(feature = "option_as_slice", since = "1.75.0")]
854-
pub fn as_mut_slice(&mut self) -> &mut [T] {
855+
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
856+
pub const fn as_mut_slice(&mut self) -> &mut [T] {
855857
// SAFETY: When the `Option` is `Some`, we're using the actual pointer
856858
// to the payload, with a length of 1, so this is equivalent to
857859
// `slice::from_mut`, and thus is safe.
@@ -867,7 +869,7 @@ impl<T> Option<T> {
867869
unsafe {
868870
slice::from_raw_parts_mut(
869871
(self as *mut Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
870-
usize::from(self.is_some()),
872+
self.is_some() as usize,
871873
)
872874
}
873875
}

core/tests/option.rs

+9
Original file line numberDiff line numberDiff line change
@@ -574,4 +574,13 @@ fn as_slice() {
574574
assert_eq!(Some(43).as_mut_slice(), &[43]);
575575
assert_eq!(None::<i32>.as_slice(), &[]);
576576
assert_eq!(None::<i32>.as_mut_slice(), &[]);
577+
578+
const A: &[u32] = Some(44).as_slice();
579+
const B: &[u32] = None.as_slice();
580+
const _: () = {
581+
let [45] = Some(45).as_mut_slice() else { panic!() };
582+
let []: &[u32] = None.as_mut_slice() else { panic!() };
583+
};
584+
assert_eq!(A, &[44]);
585+
assert_eq!(B, &[]);
577586
}

0 commit comments

Comments
 (0)