diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-10-24 15:48:44 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-24 15:48:44 +0200 |
| commit | c16ee19dd4d81d3b1150d67cfb4ea84c826f4c36 (patch) | |
| tree | 1e6fc487449390e55fda1753491e6bf6eefd2ba4 | |
| parent | b8376050127b3d1806ae88e6916ddaf330ca699c (diff) | |
| parent | 5f390cfb722cf95b0df81f9563bf97b1663cff9e (diff) | |
| download | rust-c16ee19dd4d81d3b1150d67cfb4ea84c826f4c36.tar.gz rust-c16ee19dd4d81d3b1150d67cfb4ea84c826f4c36.zip | |
Rollup merge of #90162 - WaffleLapkin:const_array_slice_from_ref_mut, r=oli-obk
Mark `{array, slice}::{from_ref, from_mut}` as const fn
This PR marks the following APIs as `const`:
```rust
// core::array
pub const fn from_ref<T>(s: &T) -> &[T; 1];
pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1];
// core::slice
pub const fn from_ref<T>(s: &T) -> &[T];
pub const fn from_mut<T>(s: &mut T) -> &mut [T];
```
Note that `from_ref` methods require `const_raw_ptr_deref` feature (which seems totally fine, since it's being stabilized, see #89551), `from_mut` methods require `const_mut_refs` (which seems fine too since this PR marks `from_mut` functions as const unstable).
r? ````@oli-obk````
| -rw-r--r-- | library/core/src/array/mod.rs | 6 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 2 | ||||
| -rw-r--r-- | library/core/src/slice/raw.rs | 6 | ||||
| -rw-r--r-- | library/core/tests/array.rs | 5 | ||||
| -rw-r--r-- | library/core/tests/lib.rs | 2 | ||||
| -rw-r--r-- | library/core/tests/slice.rs | 8 |
6 files changed, 25 insertions, 4 deletions
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 73340fda2cb..811850af367 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<T>(s: &T) -> &[T; 1] { +#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")] +pub const fn from_ref<T>(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<T>(s: &mut T) -> &mut [T; 1] { +#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")] +pub const fn from_mut<T>(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 58a170401e7..63c42068aad 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 eda50dc287f..ad38aaf9f83 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<T>(s: &T) -> &[T] { +#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +pub const fn from_ref<T>(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<T>(s: &mut T) -> &mut [T] { +#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +pub const fn from_mut<T>(s: &mut T) -> &mut [T] { array::from_mut(s) } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 1d4307ca0fb..7dc071b7423 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 507a79c3de1..e1ba5020a50 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 7a008345243..8d05e47edf4 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2147,6 +2147,14 @@ fn test_slice_run_destructors() { } #[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 let mut a = [MaybeUninit::<u8>::uninit(); 10]; |
