Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More methods for str boxes. (reduce Box<[u8]> ↔ Box<str> transmutes) #41258

Merged
merged 1 commit into from
Apr 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/doc/unstable-book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions src/doc/unstable-book/src/library-features/str-box-extras.md
Original file line number Diff line number Diff line change
@@ -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

------------------------


18 changes: 13 additions & 5 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()) }
}
}

Expand Down Expand Up @@ -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())
}
}
}
Expand Down Expand Up @@ -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)
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
21 changes: 21 additions & 0 deletions src/liballoc/str.rs
Original file line number Diff line number Diff line change
@@ -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)
}
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
11 changes: 10 additions & 1 deletion src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1398,7 +1399,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) }
}
}

Expand Down