diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 73340fda2cbcc..811850af3678d 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -85,14 +85,16 @@ where /// Converts a reference to `T` into a reference to an array of length 1 (without copying). #[stable(feature = "array_from_ref", since = "1.53.0")] -pub fn from_ref(s: &T) -> &[T; 1] { +#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")] +pub const fn from_ref(s: &T) -> &[T; 1] { // SAFETY: Converting `&T` to `&[T; 1]` is sound. unsafe { &*(s as *const T).cast::<[T; 1]>() } } /// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying). #[stable(feature = "array_from_ref", since = "1.53.0")] -pub fn from_mut(s: &mut T) -> &mut [T; 1] { +#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")] +pub const fn from_mut(s: &mut T) -> &mut [T; 1] { // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound. unsafe { &mut *(s as *mut T).cast::<[T; 1]>() } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 58a170401e7c1..63c42068aadf9 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -136,6 +136,8 @@ #![feature(ptr_metadata)] #![feature(slice_ptr_get)] #![feature(variant_count)] +#![feature(const_array_from_ref)] +#![feature(const_slice_from_ref)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index eda50dc287f6c..ad38aaf9f8300 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -138,12 +138,14 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] -pub fn from_ref(s: &T) -> &[T] { +#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +pub const fn from_ref(s: &T) -> &[T] { array::from_ref(s) } /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] -pub fn from_mut(s: &mut T) -> &mut [T] { +#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 1d4307ca0fbda..7dc071b74235d 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -7,6 +7,11 @@ fn array_from_ref() { let value: String = "Hello World!".into(); let arr: &[String; 1] = array::from_ref(&value); assert_eq!(&[value.clone()], arr); + + const VALUE: &&str = &"Hello World!"; + const ARR: &[&str; 1] = array::from_ref(VALUE); + assert_eq!(&[*VALUE], ARR); + assert!(core::ptr::eq(VALUE, &ARR[0])); } #[test] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 507a79c3de1c4..e1ba5020a50bb 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -74,6 +74,8 @@ #![feature(trusted_random_access)] #![feature(unsize)] #![feature(unzip_option)] +#![feature(const_array_from_ref)] +#![feature(const_slice_from_ref)] #![deny(unsafe_op_in_unsafe_fn)] extern crate test; diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 7a008345243c0..8d05e47edf489 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2146,6 +2146,14 @@ fn test_slice_run_destructors() { assert_eq!(x.get(), 1); } +#[test] +fn test_const_from_ref() { + const VALUE: &i32 = &1; + const SLICE: &[i32] = core::slice::from_ref(VALUE); + + assert!(core::ptr::eq(VALUE, &SLICE[0])) +} + #[test] fn test_slice_fill_with_uninit() { // This should not UB. See #87891