about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/unstable-book/src/SUMMARY.md1
-rw-r--r--src/doc/unstable-book/src/library-features/str-box-extras.md9
-rw-r--r--src/liballoc/boxed.rs18
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/str.rs21
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/str.rs11
-rw-r--r--src/libcollections/string.rs5
8 files changed, 60 insertions, 8 deletions
diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md
index 4a5d850d66d..2cb37630112 100644
--- a/src/doc/unstable-book/src/SUMMARY.md
+++ b/src/doc/unstable-book/src/SUMMARY.md
@@ -202,6 +202,7 @@
     - [str_checked_slicing](library-features/str-checked-slicing.md)
     - [str_escape](library-features/str-escape.md)
     - [str_internals](library-features/str-internals.md)
+    - [str_box_extras](library-features/str-box-extras.md)
     - [str_mut_extras](library-features/str-mut-extras.md)
     - [test](library-features/test.md)
     - [thread_id](library-features/thread-id.md)
diff --git a/src/doc/unstable-book/src/library-features/str-box-extras.md b/src/doc/unstable-book/src/library-features/str-box-extras.md
new file mode 100644
index 00000000000..d05dcafa84d
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/str-box-extras.md
@@ -0,0 +1,9 @@
+# `str_box_extras`
+
+The tracking issue for this feature is: [#str_box_extras]
+
+[#str_box_extras]: https://github.com/rust-lang/rust/issues/41119
+
+------------------------
+
+
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 43b0d72186a..b03e3bb7a4b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -68,6 +68,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut};
 use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
 use core::ptr::{self, Unique};
 use core::convert::From;
+use str::from_boxed_utf8_unchecked;
 
 /// A value that represents the heap. This is the default place that the `box`
 /// keyword allocates into when no place is supplied.
@@ -320,8 +321,7 @@ impl<T> Default for Box<[T]> {
 #[stable(feature = "default_box_extra", since = "1.17.0")]
 impl Default for Box<str> {
     fn default() -> Box<str> {
-        let default: Box<[u8]> = Default::default();
-        unsafe { mem::transmute(default) }
+        unsafe { from_boxed_utf8_unchecked(Default::default()) }
     }
 }
 
@@ -366,7 +366,7 @@ impl Clone for Box<str> {
         let buf = RawVec::with_capacity(len);
         unsafe {
             ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len);
-            mem::transmute(buf.into_box()) // bytes to str ~magic
+            from_boxed_utf8_unchecked(buf.into_box())
         }
     }
 }
@@ -441,8 +441,16 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
 #[stable(feature = "box_from_slice", since = "1.17.0")]
 impl<'a> From<&'a str> for Box<str> {
     fn from(s: &'a str) -> Box<str> {
-        let boxed: Box<[u8]> = Box::from(s.as_bytes());
-        unsafe { mem::transmute(boxed) }
+        unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
+    }
+}
+
+#[stable(feature = "boxed_str_conv", since = "1.18.0")]
+impl From<Box<str>> for Box<[u8]> {
+    fn from(s: Box<str>) -> Self {
+        unsafe {
+            mem::transmute(s)
+        }
     }
 }
 
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index c70d82392f9..fee0e1eb260 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -129,6 +129,8 @@ mod boxed_test;
 pub mod arc;
 pub mod rc;
 pub mod raw_vec;
+#[unstable(feature = "str_box_extras", issue = "41119")]
+pub mod str;
 pub mod oom;
 
 pub use oom::oom;
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
new file mode 100644
index 00000000000..c87db16a0f4
--- /dev/null
+++ b/src/liballoc/str.rs
@@ -0,0 +1,21 @@
+// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Methods for dealing with boxed strings.
+use core::mem;
+
+use boxed::Box;
+
+/// Converts a boxed slice of bytes to a boxed string slice without checking
+/// that the string contains valid UTF-8.
+#[unstable(feature = "str_box_extras", issue = "41119")]
+pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
+    mem::transmute(v)
+}
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 8d056afdb57..842f2f44fff 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -60,6 +60,7 @@
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(str_internals)]
+#![feature(str_box_extras)]
 #![feature(str_mut_extras)]
 #![feature(trusted_len)]
 #![feature(unicode)]
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 8168e02bf82..964660183e7 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -70,14 +70,17 @@ pub use core::str::{Matches, RMatches};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::{MatchIndices, RMatchIndices};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
+pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
+#[unstable(feature = "str_box_extras", issue = "41119")]
+pub use alloc::str::from_boxed_utf8_unchecked;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use std_unicode::str::SplitWhitespace;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::pattern;
 
+
 #[unstable(feature = "slice_concat_ext",
            reason = "trait should not have to exist",
            issue = "27747")]
@@ -1715,6 +1718,12 @@ impl str {
         core_str::StrExt::parse(self)
     }
 
+    /// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
+    #[unstable(feature = "str_box_extras", issue = "41119")]
+    pub fn into_boxed_bytes(self: Box<str>) -> Box<[u8]> {
+        self.into()
+    }
+
     /// Replaces all matches of a pattern with another string.
     ///
     /// `replace` creates a new [`String`], and copies the data from this string slice into it.
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 0a82fda09cb..aa9628c535a 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -56,10 +56,11 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use alloc::str as alloc_str;
+
 use core::fmt;
 use core::hash;
 use core::iter::{FromIterator, FusedIterator};
-use core::mem;
 use core::ops::{self, Add, AddAssign, Index, IndexMut};
 use core::ptr;
 use core::str as core_str;
@@ -1463,7 +1464,7 @@ impl String {
     #[stable(feature = "box_str", since = "1.4.0")]
     pub fn into_boxed_str(self) -> Box<str> {
         let slice = self.vec.into_boxed_slice();
-        unsafe { mem::transmute::<Box<[u8]>, Box<str>>(slice) }
+        unsafe { alloc_str::from_boxed_utf8_unchecked(slice) }
     }
 }