From 35c65a8c0cf018d472afec5adf9da8242adc8c23 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Wed, 19 Jun 2024 21:44:47 +0100 Subject: [PATCH] Make Option::as_[mut_]slice const --- library/core/src/option.rs | 10 ++++++---- library/core/tests/option.rs | 9 +++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4d6ba2fa3b3..8ec7716012f 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -797,7 +797,8 @@ pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { #[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, ) } } diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index b1b9492f182..336a79a02ce 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -574,4 +574,13 @@ fn as_slice() { assert_eq!(Some(43).as_mut_slice(), &[43]); assert_eq!(None::.as_slice(), &[]); assert_eq!(None::.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, &[]); }