Constified str::from_utf8_unchecked

This commit is contained in:
rodrimati1992 2020-08-04 14:38:42 -03:00 committed by GitHub
parent 5f6bd6ec0a
commit 0f7817f99e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 12 deletions

View File

@ -381,6 +381,15 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
Ok(unsafe { from_utf8_unchecked_mut(v) }) Ok(unsafe { from_utf8_unchecked_mut(v) })
} }
#[repr(C)]
union StrOrSlice<'a> {
str: &'a str,
slice: &'a [u8],
}
/// Converts a slice of bytes to a string slice without checking /// Converts a slice of bytes to a string slice without checking
/// that the string contains valid UTF-8. /// that the string contains valid UTF-8.
/// ///
@ -414,14 +423,16 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "none")]
// SAFETY: the caller must guarantee that the bytes `v` #[allow(unused_attributes)]
// are valid UTF-8, thus the cast to `*const str` is safe. #[allow_internal_unstable(const_fn_union)]
// Also, the pointer dereference is safe because that pointer pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
// comes from a reference which is guaranteed to be valid for reads. // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
unsafe { &*(v as *const [u8] as *const str) } // Also relies on `&str` and `&[u8]` having the same layout.
unsafe{ StrOrSlice{ slice: v }.str }
} }
/// Converts a slice of bytes to a string slice without checking /// Converts a slice of bytes to a string slice without checking
/// that the string contains valid UTF-8; mutable version. /// that the string contains valid UTF-8; mutable version.
/// ///
@ -2350,13 +2361,9 @@ impl str {
#[allow(unused_attributes)] #[allow(unused_attributes)]
#[allow_internal_unstable(const_fn_union)] #[allow_internal_unstable(const_fn_union)]
pub const fn as_bytes(&self) -> &[u8] { pub const fn as_bytes(&self) -> &[u8] {
#[repr(C)]
union Slices<'a> {
str: &'a str,
slice: &'a [u8],
}
// SAFETY: const sound because we transmute two types with the same layout // SAFETY: const sound because we transmute two types with the same layout
unsafe { Slices { str: self }.slice } unsafe { StrOrSlice { str: self }.slice }
} }
/// Converts a mutable string slice to a mutable byte slice. /// Converts a mutable string slice to a mutable byte slice.