diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index fdb23529599c8..91ebeb79ab7f6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -132,6 +132,7 @@ #![feature(const_size_of_val)] #![feature(const_slice_from_raw_parts)] #![feature(const_slice_ptr_len)] +#![feature(const_str_from_raw_parts)] #![feature(const_str_from_utf8_unchecked_mut)] #![feature(const_swap)] #![feature(const_trait_impl)] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 8ab72e6aeeafa..c548f531e8d6c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -292,6 +292,69 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { from_raw_parts_mut(data.cast(), len) } +/// Forms a raw string slice from a pointer and a length. +/// +/// The `len` argument is the number of **bytes**, not the number of characters. +/// +/// This function is safe, but actually using the return value is unsafe. +/// See the documentation of [`slice::from_raw_parts`] for slice safety requirements and [`str::from_utf8`] for string safety requirements. +/// +/// [`slice::from_raw_parts`]: crate::slice::from_raw_parts +/// [`str::from_utf8`]: crate::str::from_utf8 +/// +/// # Examples +/// +/// ```rust +/// #![feature(str_from_raw_parts)] +/// use std::ptr; +/// +/// // create a string slice pointer when starting out with a pointer to the first element +/// let x = "abc"; +/// let raw_pointer = x.as_ptr(); +/// let str = ptr::str_from_raw_parts(raw_pointer, 3); +/// assert_eq!(unsafe { &*str }, x); +/// ``` +#[inline] +#[unstable(feature = "str_from_raw_parts", issue = "none")] +#[rustc_const_unstable(feature = "const_str_from_raw_parts", issue = "none")] +pub const fn str_from_raw_parts(data: *const u8, len: usize) -> *const str { + from_raw_parts(data.cast(), len) +} + +/// Performs the same functionality as [`str_from_raw_parts`], except that a +/// raw mutable string slice is returned, as opposed to a raw immutable string slice. +/// +/// See the documentation of [`slice_from_raw_parts`] for more details. +/// +/// This function is safe, but actually using the return value is unsafe. +/// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements and [`str::from_utf8_mut`] for string safety requirements. +/// +/// [`slice::from_raw_parts_mut`]: crate::slice::from_raw_parts_mut +/// [`str::from_utf8_mut`]: crate::str::from_utf8_mut +/// +/// # Examples +/// +/// ```rust +/// #![feature(str_from_raw_parts)] +/// use std::ptr; +/// +/// let mut x = [b'a', b'b', b'c']; +/// let raw_pointer = x.as_mut_ptr(); +/// let str = ptr::str_from_raw_parts_mut(raw_pointer, 3); +/// +/// unsafe { +/// (*(str as *mut [u8]))[2] = b'z'; // assign a value at an index in the string slice +/// }; +/// +/// assert_eq!(unsafe { &*str }, "abz"); +/// ``` +#[inline] +#[unstable(feature = "str_from_raw_parts", issue = "none")] +#[rustc_const_unstable(feature = "const_str_from_raw_parts", issue = "none")] +pub const fn str_from_raw_parts_mut(data: *mut u8, len: usize) -> *mut str { + from_raw_parts_mut(data.cast(), len) +} + /// Swaps the values at two mutable locations of the same type, without /// deinitializing either. /// diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 58110b0680943..292650b40f357 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -634,6 +634,42 @@ impl NonNull<[T]> { } } +impl NonNull { + /// Creates a non-null raw string slice from a thin pointer and a length. + /// + /// The `len` argument is the number of **bytes**, not the number of characters. + /// + /// This function is safe, but dereferencing the return value is unsafe. + /// See the documentation of [`slice::from_raw_parts`] for slice safety + /// requirements and [`str::from_utf8`] for string safety requirements. + /// + /// [`str::from_utf8`]: crate::str::from_utf8 + /// + /// # Examples + /// + /// ```rust + /// #![feature(nonnull_str_from_raw_parts)] + /// + /// use std::ptr::NonNull; + /// + /// // create a string slice pointer when starting out with a pointer to the first byte + /// let mut x = [b'a', b'b', b'c']; + /// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap(); + /// let str = NonNull::str_from_raw_parts(nonnull_pointer, 3); + /// assert_eq!(unsafe { str.as_ref() }, "abc"); + /// ``` + /// + /// (Note that this example artificially demonstrates a use of this method, + /// but `let str = NonNull::from(str::from_utf8_unchecked(&x[..]));` would be a better way to write code like this.) + #[unstable(feature = "nonnull_str_from_raw_parts", issue = "none")] + #[rustc_const_unstable(feature = "const_nonnull_str_from_raw_parts", issue = "none")] + #[inline] + pub const fn str_from_raw_parts(data: NonNull, len: usize) -> Self { + // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null + unsafe { Self::new_unchecked(super::str_from_raw_parts_mut(data.as_ptr(), len)) } + } +} + #[stable(feature = "nonnull", since = "1.25.0")] impl Clone for NonNull { #[inline]