From 0f7817f99e69630d9bf2aecc871523de536f415a Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Tue, 4 Aug 2020 14:38:42 -0300 Subject: [PATCH 1/7] Constified str::from_utf8_unchecked --- library/core/src/str/mod.rs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 9d7e38d0e18..d8698d6c41e 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -381,6 +381,15 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { 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 /// that the string contains valid UTF-8. /// @@ -414,14 +423,16 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { - // SAFETY: the caller must guarantee that the bytes `v` - // are valid UTF-8, thus the cast to `*const str` is safe. - // Also, the pointer dereference is safe because that pointer - // comes from a reference which is guaranteed to be valid for reads. - unsafe { &*(v as *const [u8] as *const str) } +#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "none")] +#[allow(unused_attributes)] +#[allow_internal_unstable(const_fn_union)] +pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { + // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8. + // 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 /// that the string contains valid UTF-8; mutable version. /// @@ -2350,13 +2361,9 @@ impl str { #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] 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 - unsafe { Slices { str: self }.slice } + unsafe { StrOrSlice { str: self }.slice } } /// Converts a mutable string slice to a mutable byte slice. From 750912537d09e62dc0465e493f3bacc63ef63a4f Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Wed, 5 Aug 2020 14:01:44 -0300 Subject: [PATCH 2/7] Added issue number, removed trailing whitespace --- library/core/src/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index d8698d6c41e..1aa242eedec 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -22,7 +22,7 @@ use crate::slice::{self, SliceIndex, Split as SliceSplit}; pub mod pattern; -#[unstable(feature = "str_internals", issue = "none")] +#[unstable(feature = "str_internals", issue = "75196")] #[allow(missing_docs)] pub mod lossy; @@ -2361,7 +2361,7 @@ impl str { #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn as_bytes(&self) -> &[u8] { - + // SAFETY: const sound because we transmute two types with the same layout unsafe { StrOrSlice { str: self }.slice } } From 748b0c37a93b280c2770435825775a3ddcb501ce Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Wed, 5 Aug 2020 14:05:57 -0300 Subject: [PATCH 3/7] Fixed mistake --- library/core/src/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 1aa242eedec..a6b19fe1c58 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -22,7 +22,7 @@ use crate::slice::{self, SliceIndex, Split as SliceSplit}; pub mod pattern; -#[unstable(feature = "str_internals", issue = "75196")] +#[unstable(feature = "str_internals", issue = "none")] #[allow(missing_docs)] pub mod lossy; @@ -423,7 +423,7 @@ union StrOrSlice<'a> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "none")] +#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")] #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { From 77d0d152cce8c26935c3e0ac449982f24471a6f5 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Thu, 6 Aug 2020 02:15:55 -0300 Subject: [PATCH 4/7] Made formatting consistent with surrounding code --- library/core/src/str/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index a6b19fe1c58..fef1ebef4c1 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -381,15 +381,12 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { 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 /// that the string contains valid UTF-8. /// @@ -429,10 +426,9 @@ union StrOrSlice<'a> { pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8. // Also relies on `&str` and `&[u8]` having the same layout. - unsafe{ StrOrSlice{ slice: v }.str } + unsafe { StrOrSlice { slice: v }.str } } - /// Converts a slice of bytes to a string slice without checking /// that the string contains valid UTF-8; mutable version. /// From a915bbf780a6893e10d7df8af772caa18073d389 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Thu, 6 Aug 2020 04:00:59 -0300 Subject: [PATCH 5/7] Removed blank line that caused CI error --- library/core/src/str/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index fef1ebef4c1..d2f5b408fb9 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2357,7 +2357,6 @@ impl str { #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn as_bytes(&self) -> &[u8] { - // SAFETY: const sound because we transmute two types with the same layout unsafe { StrOrSlice { str: self }.slice } } From 1767c8bdf0c57ca10862dae98a4955044ccc1cbf Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Thu, 13 Aug 2020 15:56:23 -0300 Subject: [PATCH 6/7] Replaced union with transmute --- library/core/src/str/mod.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index d2f5b408fb9..80f01dcdf02 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -381,12 +381,6 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { 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 /// that the string contains valid UTF-8. /// @@ -422,11 +416,11 @@ union StrOrSlice<'a> { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")] #[allow(unused_attributes)] -#[allow_internal_unstable(const_fn_union)] +#[allow_internal_unstable(const_fn_transmute)] pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8. // Also relies on `&str` and `&[u8]` having the same layout. - unsafe { StrOrSlice { slice: v }.str } + unsafe { mem::transmute(self) } } /// Converts a slice of bytes to a string slice without checking @@ -2355,10 +2349,10 @@ impl str { #[rustc_const_stable(feature = "str_as_bytes", since = "1.32.0")] #[inline(always)] #[allow(unused_attributes)] - #[allow_internal_unstable(const_fn_union)] + #[allow_internal_unstable(const_fn_transmute)] pub const fn as_bytes(&self) -> &[u8] { // SAFETY: const sound because we transmute two types with the same layout - unsafe { StrOrSlice { str: self }.slice } + unsafe { mem::transmute(self) } } /// Converts a mutable string slice to a mutable byte slice. From 18377082f1a1ba2f07193f12b9d571d25b670ff7 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Thu, 13 Aug 2020 16:08:22 -0300 Subject: [PATCH 7/7] Fixed transmute argument --- library/core/src/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 80f01dcdf02..e58babc8100 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -420,7 +420,7 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8. // Also relies on `&str` and `&[u8]` having the same layout. - unsafe { mem::transmute(self) } + unsafe { mem::transmute(v) } } /// Converts a slice of bytes to a string slice without checking