From 8b21b075f73c629c25e8225c78a2992aa6e1d874 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 09:21:44 +0200 Subject: [PATCH] Add functions to build raw slices --- src/libcore/ptr/mod.rs | 47 ++++++++++++++++++++++++++++++++++++++++ src/libcore/slice/mod.rs | 19 +++------------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 8f026a5b7d8dd..ba88fde6ebc97 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -230,6 +230,53 @@ pub const fn null() -> *const T { 0 as *const T } #[rustc_promotable] pub const fn null_mut() -> *mut T { 0 as *mut T } +#[repr(C)] +pub(crate) union Repr { + pub(crate) rust: *const [T], + rust_mut: *mut [T], + pub(crate) raw: FatPtr, +} + +#[repr(C)] +pub(crate) struct FatPtr { + data: *const T, + pub(crate) len: usize, +} + +/// Forms a slice from a pointer and a length. +/// +/// The `len` argument is the number of **elements**, not the number of bytes. +/// +/// # Examples +/// +/// ```rust +/// #![feature(slice_from_raw_parts)] +/// use std::ptr; +/// +/// // create a slice pointer when starting out with a pointer to the first element +/// let mut x = [5, 6, 7]; +/// let ptr = &mut x[0] as *mut _; +/// let slice = ptr::slice_from_raw_parts_mut(ptr, 3); +/// assert_eq!(unsafe { &*slice }[2], 7); +/// ``` +#[inline] +#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")] +pub fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { Repr { raw: FatPtr { data, len } }.rust } +} + +/// Performs the same functionality as [`from_raw_parts`], except that a +/// mutable slice is returned. +/// +/// See the documentation of [`from_raw_parts`] for more details. +/// +/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html +#[inline] +#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")] +pub fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { + unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } +} + /// Swaps the values at two mutable locations of the same type, without /// deinitializing either. /// diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index b2376cdf9fa76..af1b20a4c10cf 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -45,19 +45,6 @@ pub mod memchr; mod rotate; mod sort; -#[repr(C)] -union Repr<'a, T: 'a> { - rust: &'a [T], - rust_mut: &'a mut [T], - raw: FatPtr, -} - -#[repr(C)] -struct FatPtr { - data: *const T, - len: usize, -} - // // Extension traits // @@ -78,7 +65,7 @@ impl [T] { #[rustc_const_unstable(feature = "const_slice_len")] pub const fn len(&self) -> usize { unsafe { - Repr { rust: self }.raw.len + crate::ptr::Repr { rust: self }.raw.len } } @@ -5195,7 +5182,7 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); - Repr { raw: FatPtr { data, len } }.rust + &*ptr::slice_from_raw_parts(data, len) } /// Performs the same functionality as [`from_raw_parts`], except that a @@ -5216,7 +5203,7 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); - Repr { raw: FatPtr { data, len } }.rust_mut + &mut *ptr::slice_from_raw_parts_mut(data, len) } /// Converts a reference to T into a slice of length 1 (without copying).