about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-10-24 15:48:44 +0200
committerGitHub <noreply@github.com>2021-10-24 15:48:44 +0200
commitc16ee19dd4d81d3b1150d67cfb4ea84c826f4c36 (patch)
tree1e6fc487449390e55fda1753491e6bf6eefd2ba4
parentb8376050127b3d1806ae88e6916ddaf330ca699c (diff)
parent5f390cfb722cf95b0df81f9563bf97b1663cff9e (diff)
downloadrust-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.rs6
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/slice/raw.rs6
-rw-r--r--library/core/tests/array.rs5
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/slice.rs8
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];