From c66c6e96978cd81130587e9f4d1fa52dc1b183d6 Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Tue, 11 Apr 2017 16:02:43 -0400 Subject: [PATCH] More methods for str boxes. --- src/doc/unstable-book/src/SUMMARY.md | 1 + .../src/library-features/str-box-extras.md | 9 ++++++++ src/liballoc/boxed.rs | 18 +++++++++++----- src/liballoc/lib.rs | 2 ++ src/liballoc/str.rs | 21 +++++++++++++++++++ src/libcollections/lib.rs | 1 + src/libcollections/str.rs | 11 +++++++++- src/libcollections/string.rs | 5 +++-- 8 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/str-box-extras.md create mode 100644 src/liballoc/str.rs diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 3e0415439774c..76196173b11e5 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -207,6 +207,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 0000000000000..d05dcafa84da9 --- /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 43b0d72186a29..b03e3bb7a4bdc 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 Default for Box<[T]> { #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { - 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 { 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 { fn from(s: &'a str) -> Box { - 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> for Box<[u8]> { + fn from(s: Box) -> Self { + unsafe { + mem::transmute(s) + } } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0c01eabd593ff..418a084da6787 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -128,6 +128,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 0000000000000..c87db16a0f417 --- /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 or the MIT license +// , 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 { + mem::transmute(v) +} diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 3bea61f6220b6..c3db76e6c759d 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 8168e02bf8261..964660183e751 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` into a `Box<[u8]>` without copying or allocating. + #[unstable(feature = "str_box_extras", issue = "41119")] + pub fn into_boxed_bytes(self: Box) -> 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 8d6cf30511260..69dfb466d707e 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; @@ -1398,7 +1399,7 @@ impl String { #[stable(feature = "box_str", since = "1.4.0")] pub fn into_boxed_str(self) -> Box { let slice = self.vec.into_boxed_slice(); - unsafe { mem::transmute::, Box>(slice) } + unsafe { alloc_str::from_boxed_utf8_unchecked(slice) } } }