Skip to content

Commit

Permalink
Rollup merge of #90162 - WaffleLapkin:const_array_slice_from_ref_mut,…
Browse files Browse the repository at this point in the history
… 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````
  • Loading branch information
matthiaskrgr authored Oct 24, 2021
2 parents b837605 + 5f390cf commit c16ee19
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 4 deletions.
6 changes: 4 additions & 2 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]>() }
}
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
5 changes: 5 additions & 0 deletions library/core/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 2 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c16ee19

Please sign in to comment.