mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-24 13:43:04 +00:00
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````
This commit is contained in:
commit
c16ee19dd4
@ -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]>() }
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user