Skip to content

Commit c16ee19

Browse files
authoredOct 24, 2021
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````
2 parents b837605 + 5f390cf commit c16ee19

File tree

6 files changed

+25
-4
lines changed

6 files changed

+25
-4
lines changed
 

‎library/core/src/array/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,16 @@ where
8585

8686
/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
8787
#[stable(feature = "array_from_ref", since = "1.53.0")]
88-
pub fn from_ref<T>(s: &T) -> &[T; 1] {
88+
#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")]
89+
pub const fn from_ref<T>(s: &T) -> &[T; 1] {
8990
// SAFETY: Converting `&T` to `&[T; 1]` is sound.
9091
unsafe { &*(s as *const T).cast::<[T; 1]>() }
9192
}
9293

9394
/// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
9495
#[stable(feature = "array_from_ref", since = "1.53.0")]
95-
pub fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
96+
#[rustc_const_unstable(feature = "const_array_from_ref", issue = "90206")]
97+
pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
9698
// SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
9799
unsafe { &mut *(s as *mut T).cast::<[T; 1]>() }
98100
}

‎library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@
136136
#![feature(ptr_metadata)]
137137
#![feature(slice_ptr_get)]
138138
#![feature(variant_count)]
139+
#![feature(const_array_from_ref)]
140+
#![feature(const_slice_from_ref)]
139141
//
140142
// Language features:
141143
#![feature(abi_unadjusted)]

‎library/core/src/slice/raw.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,14 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T]
138138

139139
/// Converts a reference to T into a slice of length 1 (without copying).
140140
#[stable(feature = "from_ref", since = "1.28.0")]
141-
pub fn from_ref<T>(s: &T) -> &[T] {
141+
#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")]
142+
pub const fn from_ref<T>(s: &T) -> &[T] {
142143
array::from_ref(s)
143144
}
144145

145146
/// Converts a reference to T into a slice of length 1 (without copying).
146147
#[stable(feature = "from_ref", since = "1.28.0")]
147-
pub fn from_mut<T>(s: &mut T) -> &mut [T] {
148+
#[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")]
149+
pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
148150
array::from_mut(s)
149151
}

‎library/core/tests/array.rs

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ fn array_from_ref() {
77
let value: String = "Hello World!".into();
88
let arr: &[String; 1] = array::from_ref(&value);
99
assert_eq!(&[value.clone()], arr);
10+
11+
const VALUE: &&str = &"Hello World!";
12+
const ARR: &[&str; 1] = array::from_ref(VALUE);
13+
assert_eq!(&[*VALUE], ARR);
14+
assert!(core::ptr::eq(VALUE, &ARR[0]));
1015
}
1116

1217
#[test]

‎library/core/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
#![feature(trusted_random_access)]
7575
#![feature(unsize)]
7676
#![feature(unzip_option)]
77+
#![feature(const_array_from_ref)]
78+
#![feature(const_slice_from_ref)]
7779
#![deny(unsafe_op_in_unsafe_fn)]
7880

7981
extern crate test;

‎library/core/tests/slice.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,14 @@ fn test_slice_run_destructors() {
21462146
assert_eq!(x.get(), 1);
21472147
}
21482148

2149+
#[test]
2150+
fn test_const_from_ref() {
2151+
const VALUE: &i32 = &1;
2152+
const SLICE: &[i32] = core::slice::from_ref(VALUE);
2153+
2154+
assert!(core::ptr::eq(VALUE, &SLICE[0]))
2155+
}
2156+
21492157
#[test]
21502158
fn test_slice_fill_with_uninit() {
21512159
// This should not UB. See #87891

0 commit comments

Comments
 (0)
Please sign in to comment.