From a288bf6afbf7f98fd357b971b23ef09a66aaa8c0 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 22 Oct 2021 11:15:56 +0300 Subject: [PATCH 1/3] Mark {array,slice}::{from_ref,from_mut} as const fn --- library/core/src/array/mod.rs | 6 ++++-- library/core/src/lib.rs | 2 ++ library/core/src/slice/raw.rs | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 8d5c0510404fb..752e3fceb35e6 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 = "none")] +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 = "none")] +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 13b80c05dbb30..06497ff053967 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -135,6 +135,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..bcf3d9ba48e36 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 = "none")] +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 = "none")] +pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) } From 27d69611347142cc5f103df0923b46d670e75739 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 23 Oct 2021 20:59:15 +0300 Subject: [PATCH 2/3] Fill tracking issue for `const_slice_from_ref` and `const_array_from_ref` --- library/core/src/array/mod.rs | 4 ++-- library/core/src/slice/raw.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 752e3fceb35e6..5286ea60e3fee 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -85,7 +85,7 @@ 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")] -#[rustc_const_unstable(feature = "const_array_from_ref", issue = "none")] +#[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]>() } @@ -93,7 +93,7 @@ pub const fn from_ref(s: &T) -> &[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")] -#[rustc_const_unstable(feature = "const_array_from_ref", issue = "none")] +#[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/slice/raw.rs b/library/core/src/slice/raw.rs index bcf3d9ba48e36..ad38aaf9f8300 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -138,14 +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")] -#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "none")] +#[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")] -#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "none")] +#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) } From 5f390cfb722cf95b0df81f9563bf97b1663cff9e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 23 Oct 2021 22:51:22 +0300 Subject: [PATCH 3/3] Add tests for `const_slice_from_ref` and `const_array_from_ref` --- library/core/tests/array.rs | 5 +++++ library/core/tests/lib.rs | 2 ++ library/core/tests/slice.rs | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index b3af1328c90d4..d10bb4bce3cb9 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 cf669163d3ef2..665ec756db169 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -71,6 +71,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 b6a326f3d7368..f1691c4f05710 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