about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorClar Charr <clar@charr.xyz>2017-03-10 12:10:26 -0500
committerClar Charr <clar@charr.xyz>2017-04-09 19:13:54 -0400
commita2b28be3f8f2920d39c9c87fef968d3885753ba4 (patch)
tree79223c615a438bc59d919d9d151f4e257767443c /src/libcore
parentfa332c901575da70ac7a612609a26b752b1adc65 (diff)
downloadrust-a2b28be3f8f2920d39c9c87fef968d3885753ba4.tar.gz
rust-a2b28be3f8f2920d39c9c87fef968d3885753ba4.zip
Reduce str transmutes, add mut versions of methods.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/char.rs3
-rw-r--r--src/libcore/str/mod.rs39
2 files changed, 34 insertions, 8 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index b27c801cf89..98268e3813f 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -19,6 +19,7 @@ use char_private::is_printable;
 use convert::TryFrom;
 use fmt::{self, Write};
 use slice;
+use str::from_utf8_unchecked_mut;
 use iter::FusedIterator;
 use mem::transmute;
 
@@ -448,7 +449,7 @@ impl CharExt for char {
                     code,
                     dst.len())
             };
-            transmute(slice::from_raw_parts_mut(dst.as_mut_ptr(), len))
+            from_utf8_unchecked_mut(dst.get_unchecked_mut(..len))
         }
     }
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 352cc926994..2ceef54ffed 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -21,8 +21,8 @@ use char;
 use convert::TryFrom;
 use fmt;
 use iter::{Map, Cloned, FusedIterator};
-use mem;
 use slice::{self, SliceIndex};
+use mem;
 
 pub mod pattern;
 
@@ -300,6 +300,13 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
     Ok(unsafe { from_utf8_unchecked(v) })
 }
 
+/// Converts a mutable slice of bytes to a mutable string slice.
+#[unstable(feature = "str_mut_extras", issue = "41119")]
+pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
+    run_utf8_validation(v)?;
+    Ok(unsafe { from_utf8_unchecked_mut(v) })
+}
+
 /// Forms a str from a pointer and a length.
 ///
 /// The `len` argument is the number of bytes in the string.
@@ -325,7 +332,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
 /// str is returned.
 ///
 unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
-    mem::transmute::<&mut [u8], &mut str>(slice::from_raw_parts_mut(p, len))
+    from_utf8_unchecked_mut(slice::from_raw_parts_mut(p, len))
 }
 
 /// Converts a slice of bytes to a string slice without checking
@@ -365,6 +372,18 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
     mem::transmute(v)
 }
 
+/// Converts a slice of bytes to a string slice without checking
+/// that the string contains valid UTF-8; mutable version.
+///
+/// See the immutable version, [`from_utf8_unchecked()`][fromutf8], for more information.
+///
+/// [fromutf8]: fn.from_utf8_unchecked.html
+#[inline(always)]
+#[unstable(feature = "str_mut_extras", issue = "41119")]
+pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
+    mem::transmute(v)
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Utf8Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1474,7 +1493,6 @@ Section: Trait implementations
 mod traits {
     use cmp::Ordering;
     use ops;
-    use mem;
     use slice::{self, SliceIndex};
     use str::eq_slice;
 
@@ -1811,7 +1829,7 @@ mod traits {
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_ptr().offset(self.start as isize);
             let len = self.end - self.start;
-            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1859,7 +1877,7 @@ mod traits {
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_ptr();
-            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1905,7 +1923,7 @@ mod traits {
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_ptr().offset(self.start as isize);
             let len = slice.len() - self.start;
-            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1998,7 +2016,7 @@ mod traits {
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_ptr();
-            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -2096,6 +2114,8 @@ pub trait StrExt {
     fn is_char_boundary(&self, index: usize) -> bool;
     #[stable(feature = "core", since = "1.6.0")]
     fn as_bytes(&self) -> &[u8];
+    #[unstable(feature = "str_mut_extras", issue = "0")]
+    unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
     #[stable(feature = "core", since = "1.6.0")]
     fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
     #[stable(feature = "core", since = "1.6.0")]
@@ -2373,6 +2393,11 @@ impl StrExt for str {
         unsafe { mem::transmute(self) }
     }
 
+    #[inline]
+    unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
+        mem::transmute(self)
+    }
+
     fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
         pat.into_searcher(self).next_match().map(|(i, _)| i)
     }