Skip to content

Commit 0f7817f

Browse files
Constified str::from_utf8_unchecked
1 parent 5f6bd6e commit 0f7817f

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

library/core/src/str/mod.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,15 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
381381
Ok(unsafe { from_utf8_unchecked_mut(v) })
382382
}
383383

384+
385+
#[repr(C)]
386+
union StrOrSlice<'a> {
387+
str: &'a str,
388+
slice: &'a [u8],
389+
}
390+
391+
392+
384393
/// Converts a slice of bytes to a string slice without checking
385394
/// that the string contains valid UTF-8.
386395
///
@@ -414,14 +423,16 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
414423
/// ```
415424
#[inline]
416425
#[stable(feature = "rust1", since = "1.0.0")]
417-
pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
418-
// SAFETY: the caller must guarantee that the bytes `v`
419-
// are valid UTF-8, thus the cast to `*const str` is safe.
420-
// Also, the pointer dereference is safe because that pointer
421-
// comes from a reference which is guaranteed to be valid for reads.
422-
unsafe { &*(v as *const [u8] as *const str) }
426+
#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "none")]
427+
#[allow(unused_attributes)]
428+
#[allow_internal_unstable(const_fn_union)]
429+
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
430+
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
431+
// Also relies on `&str` and `&[u8]` having the same layout.
432+
unsafe{ StrOrSlice{ slice: v }.str }
423433
}
424434

435+
425436
/// Converts a slice of bytes to a string slice without checking
426437
/// that the string contains valid UTF-8; mutable version.
427438
///
@@ -2350,13 +2361,9 @@ impl str {
23502361
#[allow(unused_attributes)]
23512362
#[allow_internal_unstable(const_fn_union)]
23522363
pub const fn as_bytes(&self) -> &[u8] {
2353-
#[repr(C)]
2354-
union Slices<'a> {
2355-
str: &'a str,
2356-
slice: &'a [u8],
2357-
}
2364+
23582365
// SAFETY: const sound because we transmute two types with the same layout
2359-
unsafe { Slices { str: self }.slice }
2366+
unsafe { StrOrSlice { str: self }.slice }
23602367
}
23612368

23622369
/// Converts a mutable string slice to a mutable byte slice.

0 commit comments

Comments
 (0)