auto merge of #19152 : alexcrichton/rust/issue-17863, r=aturon
This commit is an implementation of [RFC 240][rfc] when applied to the standard library. It primarily deprecates the entirety of `string::raw`, `vec::raw`, `slice::raw`, and `str::raw` in favor of associated functions, methods, and other free functions. The detailed renaming is: * slice::raw::buf_as_slice => slice::from_raw_buf * slice::raw::mut_buf_as_slice => slice::from_raw_mut_buf * slice::shift_ptr => deprecated with no replacement * slice::pop_ptr => deprecated with no replacement * str::raw::from_utf8 => str::from_utf8_unchecked * str::raw::c_str_to_static_slice => str::from_c_str * str::raw::slice_bytes => deprecated for slice_unchecked (slight semantic diff) * str::raw::slice_unchecked => str.slice_unchecked * string::raw::from_parts => String::from_raw_parts * string::raw::from_buf_len => String::from_raw_buf_len * string::raw::from_buf => String::from_raw_buf * string::raw::from_utf8 => String::from_utf8_unchecked * vec::raw::from_buf => Vec::from_raw_buf All previous functions exist in their `#[deprecated]` form, and the deprecation messages indicate how to migrate to the newer variants. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0240-unsafe-api-location.md [breaking-change] Closes #17863
This commit is contained in:
commit
641e2a110d
15 changed files with 304 additions and 208 deletions
|
|
@ -106,7 +106,7 @@ pub use core::slice::{OrdSlicePrelude, SlicePrelude, Items, MutItems};
|
|||
pub use core::slice::{ImmutableIntSlice, MutableIntSlice};
|
||||
pub use core::slice::{MutSplits, MutChunks, Splits};
|
||||
pub use core::slice::{bytes, mut_ref_slice, ref_slice, CloneSlicePrelude};
|
||||
pub use core::slice::{Found, NotFound};
|
||||
pub use core::slice::{Found, NotFound, from_raw_buf, from_raw_mut_buf};
|
||||
|
||||
// Functional utilities
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
|
|||
pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
|
||||
pub use core::str::{FromStr, from_str};
|
||||
pub use core::str::{Str, StrPrelude};
|
||||
pub use core::str::{from_utf8_unchecked, from_c_str};
|
||||
pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices};
|
||||
|
||||
// FIXME(conventions): ensure bit/char conventions are followed by str's API
|
||||
|
|
@ -393,11 +394,11 @@ pub fn replace(s: &str, from: &str, to: &str) -> String {
|
|||
let mut result = String::new();
|
||||
let mut last_end = 0;
|
||||
for (start, end) in s.match_indices(from) {
|
||||
result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
|
||||
result.push_str(unsafe { s.slice_unchecked(last_end, start) });
|
||||
result.push_str(to);
|
||||
last_end = end;
|
||||
}
|
||||
result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
|
||||
result.push_str(unsafe { s.slice_unchecked(last_end, s.len()) });
|
||||
result
|
||||
}
|
||||
|
||||
|
|
@ -674,16 +675,7 @@ pub trait StrAllocating: Str {
|
|||
/// assert_eq!(s.replace("cookie monster", "little lamb"), s);
|
||||
/// ```
|
||||
fn replace(&self, from: &str, to: &str) -> String {
|
||||
let me = self.as_slice();
|
||||
let mut result = String::new();
|
||||
let mut last_end = 0;
|
||||
for (start, end) in me.match_indices(from) {
|
||||
result.push_str(unsafe{raw::slice_bytes(me, last_end, start)});
|
||||
result.push_str(to);
|
||||
last_end = end;
|
||||
}
|
||||
result.push_str(unsafe{raw::slice_bytes(me, last_end, me.len())});
|
||||
result
|
||||
replace(self.as_slice(), from, to)
|
||||
}
|
||||
|
||||
/// Given a string, makes a new string with repeated copies of it.
|
||||
|
|
|
|||
|
|
@ -297,6 +297,52 @@ impl String {
|
|||
chs.iter().map(|c| *c).collect()
|
||||
}
|
||||
|
||||
/// Creates a new `String` from a length, capacity, and pointer.
|
||||
///
|
||||
/// This is unsafe because:
|
||||
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
|
||||
/// * We assume that the `Vec` contains valid UTF-8.
|
||||
#[inline]
|
||||
#[unstable = "function just moved from string::raw"]
|
||||
pub unsafe fn from_raw_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
|
||||
String {
|
||||
vec: Vec::from_raw_parts(buf, length, capacity),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `String` from a null-terminated `*const u8` buffer.
|
||||
///
|
||||
/// This function is unsafe because we dereference memory until we find the
|
||||
/// NUL character, which is not guaranteed to be present. Additionally, the
|
||||
/// slice is not checked to see whether it contains valid UTF-8
|
||||
#[unstable = "just renamed from `mod raw`"]
|
||||
pub unsafe fn from_raw_buf(buf: *const u8) -> String {
|
||||
String::from_str(str::from_c_str(buf as *const i8))
|
||||
}
|
||||
|
||||
/// Creates a `String` from a `*const u8` buffer of the given length.
|
||||
///
|
||||
/// This function is unsafe because it blindly assumes the validity of the
|
||||
/// pointer `buf` for `len` bytes of memory. This function will copy the
|
||||
/// memory from `buf` into a new allocation (owned by the returned
|
||||
/// `String`).
|
||||
///
|
||||
/// This function is also unsafe because it does not validate that the
|
||||
/// buffer is valid UTF-8 encoded data.
|
||||
#[unstable = "just renamed from `mod raw`"]
|
||||
pub unsafe fn from_raw_buf_len(buf: *const u8, len: uint) -> String {
|
||||
String::from_utf8_unchecked(Vec::from_raw_buf(buf, len))
|
||||
}
|
||||
|
||||
/// Converts a vector of bytes to a new `String` without checking if
|
||||
/// it contains valid UTF-8. This is unsafe because it assumes that
|
||||
/// the UTF-8-ness of the vector has already been validated.
|
||||
#[inline]
|
||||
#[unstable = "awaiting stabilization"]
|
||||
pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
|
||||
String { vec: bytes }
|
||||
}
|
||||
|
||||
/// Return the underlying byte buffer, encoded as UTF-8.
|
||||
///
|
||||
/// # Example
|
||||
|
|
@ -823,12 +869,8 @@ impl<T: fmt::Show> ToString for T {
|
|||
}
|
||||
|
||||
/// Unsafe operations
|
||||
#[unstable = "waiting on raw module conventions"]
|
||||
#[deprecated]
|
||||
pub mod raw {
|
||||
use core::mem;
|
||||
use core::ptr::RawPtr;
|
||||
use core::raw::Slice;
|
||||
|
||||
use super::String;
|
||||
use vec::Vec;
|
||||
|
||||
|
|
@ -838,24 +880,20 @@ pub mod raw {
|
|||
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
|
||||
/// * We assume that the `Vec` contains valid UTF-8.
|
||||
#[inline]
|
||||
#[deprecated = "renamed to String::from_raw_parts"]
|
||||
pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
|
||||
String {
|
||||
vec: Vec::from_raw_parts(buf, length, capacity),
|
||||
}
|
||||
String::from_raw_parts(buf, length, capacity)
|
||||
}
|
||||
|
||||
/// Creates a `String` from a `*const u8` buffer of the given length.
|
||||
///
|
||||
/// This function is unsafe because of two reasons:
|
||||
///
|
||||
/// * A raw pointer is dereferenced and transmuted to `&[u8]`;
|
||||
/// * The slice is not checked to see whether it contains valid UTF-8.
|
||||
#[deprecated = "renamed to String::from_raw_buf_len"]
|
||||
pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
|
||||
use slice::CloneSliceAllocPrelude;
|
||||
let slice: &[u8] = mem::transmute(Slice {
|
||||
data: buf,
|
||||
len: len,
|
||||
});
|
||||
self::from_utf8(slice.to_vec())
|
||||
String::from_raw_buf_len(buf, len)
|
||||
}
|
||||
|
||||
/// Creates a `String` from a null-terminated `*const u8` buffer.
|
||||
|
|
@ -863,20 +901,18 @@ pub mod raw {
|
|||
/// This function is unsafe because we dereference memory until we find the NUL character,
|
||||
/// which is not guaranteed to be present. Additionally, the slice is not checked to see
|
||||
/// whether it contains valid UTF-8
|
||||
#[deprecated = "renamed to String::from_raw_buf"]
|
||||
pub unsafe fn from_buf(buf: *const u8) -> String {
|
||||
let mut len = 0;
|
||||
while *buf.offset(len) != 0 {
|
||||
len += 1;
|
||||
}
|
||||
self::from_buf_len(buf, len as uint)
|
||||
String::from_raw_buf(buf)
|
||||
}
|
||||
|
||||
/// Converts a vector of bytes to a new `String` without checking if
|
||||
/// it contains valid UTF-8. This is unsafe because it assumes that
|
||||
/// the UTF-8-ness of the vector has already been validated.
|
||||
#[inline]
|
||||
#[deprecated = "renamed to String::from_utf8_unchecked"]
|
||||
pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
|
||||
String { vec: bytes }
|
||||
String::from_utf8_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -235,12 +235,27 @@ impl<T> Vec<T> {
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[experimental]
|
||||
#[unstable = "needs finalization"]
|
||||
pub unsafe fn from_raw_parts(ptr: *mut T, length: uint,
|
||||
capacity: uint) -> Vec<T> {
|
||||
Vec { ptr: ptr, len: length, cap: capacity }
|
||||
}
|
||||
|
||||
/// Creates a vector by copying the elements from a raw pointer.
|
||||
///
|
||||
/// This function will copy `elts` contiguous elements starting at `ptr`
|
||||
/// into a new allocation owned by the returned `Vec`. The elements of the
|
||||
/// buffer are copied into the vector without cloning, as if `ptr::read()`
|
||||
/// were called on them.
|
||||
#[inline]
|
||||
#[unstable = "just renamed from raw::from_buf"]
|
||||
pub unsafe fn from_raw_buf(ptr: *const T, elts: uint) -> Vec<T> {
|
||||
let mut dst = Vec::with_capacity(elts);
|
||||
dst.set_len(elts);
|
||||
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
|
||||
dst
|
||||
}
|
||||
|
||||
/// Consumes the `Vec`, partitioning it based on a predicate.
|
||||
///
|
||||
/// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
|
||||
|
|
@ -1367,23 +1382,18 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
|
|||
}
|
||||
|
||||
/// Unsafe vector operations.
|
||||
#[unstable]
|
||||
#[deprecated]
|
||||
pub mod raw {
|
||||
use super::Vec;
|
||||
use core::ptr;
|
||||
use core::slice::SlicePrelude;
|
||||
|
||||
/// Constructs a vector from an unsafe pointer to a buffer.
|
||||
///
|
||||
/// The elements of the buffer are copied into the vector without cloning,
|
||||
/// as if `ptr::read()` were called on them.
|
||||
#[inline]
|
||||
#[unstable]
|
||||
#[deprecated = "renamed to Vec::from_raw_buf"]
|
||||
pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
|
||||
let mut dst = Vec::with_capacity(elts);
|
||||
dst.set_len(elts);
|
||||
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
|
||||
dst
|
||||
Vec::from_raw_buf(ptr, elts)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue