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
|
|
@ -1559,15 +1559,55 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
|
|||
}
|
||||
}
|
||||
|
||||
/// Forms a slice from a pointer and a length.
|
||||
///
|
||||
/// The pointer given is actually a reference to the base of the slice. This
|
||||
/// reference is used to give a concrete lifetime to tie the returned slice to.
|
||||
/// Typically this should indicate that the slice is valid for as long as the
|
||||
/// pointer itself is valid.
|
||||
///
|
||||
/// The `len` argument is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// This function is unsafe as there is no guarantee that the given pointer is
|
||||
/// valid for `len` elements, nor whether the lifetime provided is a suitable
|
||||
/// lifetime for the returned slice.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::slice;
|
||||
///
|
||||
/// // manifest a slice out of thin air!
|
||||
/// let ptr = 0x1234 as *const uint;
|
||||
/// let amt = 10;
|
||||
/// unsafe {
|
||||
/// let slice = slice::from_raw_buf(&ptr, amt);
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "just renamed from `mod raw`"]
|
||||
pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
|
||||
transmute(RawSlice { data: *p, len: len })
|
||||
}
|
||||
|
||||
|
||||
/// Performs the same functionality as `from_raw_buf`, except that a mutable
|
||||
/// slice is returned.
|
||||
///
|
||||
/// This function is unsafe for the same reasons as `from_raw_buf`, as well as
|
||||
/// not being able to provide a non-aliasing guarantee of the returned mutable
|
||||
/// slice.
|
||||
#[inline]
|
||||
#[unstable = "just renamed from `mod raw`"]
|
||||
pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
|
||||
transmute(RawSlice { data: *p as *const T, len: len })
|
||||
}
|
||||
|
||||
//
|
||||
// Submodules
|
||||
//
|
||||
|
||||
/// Unsafe operations
|
||||
#[experimental = "needs review"]
|
||||
#[deprecated]
|
||||
pub mod raw {
|
||||
use mem::transmute;
|
||||
use ptr::RawPtr;
|
||||
|
|
@ -1579,6 +1619,7 @@ pub mod raw {
|
|||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[deprecated = "renamed to slice::from_raw_buf"]
|
||||
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
|
||||
-> U {
|
||||
f(transmute(Slice {
|
||||
|
|
@ -1592,6 +1633,7 @@ pub mod raw {
|
|||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[deprecated = "renamed to slice::from_raw_mut_buf"]
|
||||
pub unsafe fn mut_buf_as_slice<T,
|
||||
U>(
|
||||
p: *mut T,
|
||||
|
|
@ -1610,6 +1652,7 @@ pub mod raw {
|
|||
* if the slice is empty. O(1).
|
||||
*/
|
||||
#[inline]
|
||||
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
|
||||
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
|
||||
if slice.len == 0 { return None; }
|
||||
let head: *const T = slice.data;
|
||||
|
|
@ -1623,7 +1666,8 @@ pub mod raw {
|
|||
* slice so it no longer contains that element. Returns None
|
||||
* if the slice is empty. O(1).
|
||||
*/
|
||||
#[inline]
|
||||
#[inline]
|
||||
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
|
||||
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
|
||||
if slice.len == 0 { return None; }
|
||||
let tail: *const T = slice.data.offset((slice.len - 1) as int);
|
||||
|
|
|
|||
|
|
@ -19,18 +19,19 @@
|
|||
pub use self::Utf16Item::*;
|
||||
pub use self::Searcher::{Naive, TwoWay, TwoWayLong};
|
||||
|
||||
use mem;
|
||||
use char;
|
||||
use char::Char;
|
||||
use char;
|
||||
use cmp::{Eq, mod};
|
||||
use default::Default;
|
||||
use iter::{Map, Iterator};
|
||||
use iter::{DoubleEndedIterator, ExactSize};
|
||||
use iter::range;
|
||||
use iter::{DoubleEndedIterator, ExactSize};
|
||||
use iter::{Map, Iterator};
|
||||
use kinds::Sized;
|
||||
use mem;
|
||||
use num::Int;
|
||||
use option::{Option, None, Some};
|
||||
use raw::Repr;
|
||||
use ptr::RawPtr;
|
||||
use raw::{Repr, Slice};
|
||||
use slice::{mod, SlicePrelude};
|
||||
use uint;
|
||||
|
||||
|
|
@ -82,8 +83,39 @@ Section: Creating a string
|
|||
/// Returns None if the slice is not utf-8.
|
||||
pub fn from_utf8<'a>(v: &'a [u8]) -> Option<&'a str> {
|
||||
if is_utf8(v) {
|
||||
Some(unsafe { raw::from_utf8(v) })
|
||||
} else { None }
|
||||
Some(unsafe { from_utf8_unchecked(v) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a slice of bytes to a string slice without checking
|
||||
/// that the string contains valid UTF-8.
|
||||
pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
|
||||
mem::transmute(v)
|
||||
}
|
||||
|
||||
/// Constructs a static string slice from a given raw pointer.
|
||||
///
|
||||
/// This function will read memory starting at `s` until it finds a 0, and then
|
||||
/// transmute the memory up to that point as a string slice, returning the
|
||||
/// corresponding `&'static str` value.
|
||||
///
|
||||
/// This function is unsafe because the caller must ensure the C string itself
|
||||
/// has the static lifetime and that the memory `s` is valid up to and including
|
||||
/// the first null byte.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the string pointed to by `s` is not valid UTF-8.
|
||||
pub unsafe fn from_c_str(s: *const i8) -> &'static str {
|
||||
let s = s as *const u8;
|
||||
let mut len = 0u;
|
||||
while *s.offset(len as int) != 0 {
|
||||
len += 1u;
|
||||
}
|
||||
let v: &'static [u8] = ::mem::transmute(Slice { data: s, len: len });
|
||||
from_utf8(v).expect("from_c_str passed invalid utf-8 data")
|
||||
}
|
||||
|
||||
/// Something that can be used to compare against a character
|
||||
|
|
@ -352,8 +384,8 @@ impl<'a, Sep: CharEq> Iterator<&'a str> for CharSplits<'a, Sep> {
|
|||
}
|
||||
match next_split {
|
||||
Some((a, b)) => unsafe {
|
||||
let elt = raw::slice_unchecked(self.string, 0, a);
|
||||
self.string = raw::slice_unchecked(self.string, b, self.string.len());
|
||||
let elt = self.string.slice_unchecked(0, a);
|
||||
self.string = self.string.slice_unchecked(b, self.string.len());
|
||||
Some(elt)
|
||||
},
|
||||
None => self.get_end(),
|
||||
|
|
@ -394,8 +426,8 @@ for CharSplits<'a, Sep> {
|
|||
}
|
||||
match next_split {
|
||||
Some((a, b)) => unsafe {
|
||||
let elt = raw::slice_unchecked(self.string, b, len);
|
||||
self.string = raw::slice_unchecked(self.string, 0, a);
|
||||
let elt = self.string.slice_unchecked(b, len);
|
||||
self.string = self.string.slice_unchecked(0, a);
|
||||
Some(elt)
|
||||
},
|
||||
None => { self.finished = true; Some(self.string) }
|
||||
|
|
@ -1112,8 +1144,8 @@ const CONT_MASK: u8 = 0b0011_1111u8;
|
|||
const TAG_CONT_U8: u8 = 0b1000_0000u8;
|
||||
|
||||
/// Unsafe operations
|
||||
#[deprecated]
|
||||
pub mod raw {
|
||||
use mem;
|
||||
use ptr::RawPtr;
|
||||
use raw::Slice;
|
||||
use slice::SlicePrelude;
|
||||
|
|
@ -1121,13 +1153,15 @@ pub mod raw {
|
|||
|
||||
/// Converts a slice of bytes to a string slice without checking
|
||||
/// that the string contains valid UTF-8.
|
||||
#[deprecated = "renamed to str::from_utf8_unchecked"]
|
||||
pub unsafe fn from_utf8<'a>(v: &'a [u8]) -> &'a str {
|
||||
mem::transmute(v)
|
||||
super::from_utf8_unchecked(v)
|
||||
}
|
||||
|
||||
/// Form a slice from a C string. Unsafe because the caller must ensure the
|
||||
/// C string has the static lifetime, or else the return value may be
|
||||
/// invalidated later.
|
||||
#[deprecated = "renamed to str::from_c_str"]
|
||||
pub unsafe fn c_str_to_static_slice(s: *const i8) -> &'static str {
|
||||
let s = s as *const u8;
|
||||
let mut curr = s;
|
||||
|
|
@ -1150,10 +1184,11 @@ pub mod raw {
|
|||
/// If begin is greater than end.
|
||||
/// If end is greater than the length of the string.
|
||||
#[inline]
|
||||
#[deprecated = "call the slice_unchecked method instead"]
|
||||
pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
|
||||
assert!(begin <= end);
|
||||
assert!(end <= s.len());
|
||||
slice_unchecked(s, begin, end)
|
||||
s.slice_unchecked(begin, end)
|
||||
}
|
||||
|
||||
/// Takes a bytewise (not UTF-8) slice from a string.
|
||||
|
|
@ -1162,11 +1197,9 @@ pub mod raw {
|
|||
///
|
||||
/// Caller must check slice boundaries!
|
||||
#[inline]
|
||||
#[deprecated = "this has moved to a method on `str` directly"]
|
||||
pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
|
||||
mem::transmute(Slice {
|
||||
data: s.as_ptr().offset(begin as int),
|
||||
len: end - begin,
|
||||
})
|
||||
s.slice_unchecked(begin, end)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1566,6 +1599,14 @@ pub trait StrPrelude for Sized? {
|
|||
/// ```
|
||||
fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str;
|
||||
|
||||
/// Takes a bytewise (not UTF-8) slice from a string.
|
||||
///
|
||||
/// Returns the substring from [`begin`..`end`).
|
||||
///
|
||||
/// Caller must check both UTF-8 character boundaries and the boundaries of
|
||||
/// the entire slice as well.
|
||||
unsafe fn slice_unchecked<'a>(&'a self, begin: uint, end: uint) -> &'a str;
|
||||
|
||||
/// Returns true if `needle` is a prefix of the string.
|
||||
///
|
||||
/// # Example
|
||||
|
|
@ -2012,7 +2053,7 @@ impl StrPrelude for str {
|
|||
if begin <= end &&
|
||||
self.is_char_boundary(begin) &&
|
||||
self.is_char_boundary(end) {
|
||||
unsafe { raw::slice_unchecked(self, begin, end) }
|
||||
unsafe { self.slice_unchecked(begin, end) }
|
||||
} else {
|
||||
slice_error_fail(self, begin, end)
|
||||
}
|
||||
|
|
@ -2022,7 +2063,7 @@ impl StrPrelude for str {
|
|||
fn slice_from(&self, begin: uint) -> &str {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(begin) {
|
||||
unsafe { raw::slice_unchecked(self, begin, self.len()) }
|
||||
unsafe { self.slice_unchecked(begin, self.len()) }
|
||||
} else {
|
||||
slice_error_fail(self, begin, self.len())
|
||||
}
|
||||
|
|
@ -2032,7 +2073,7 @@ impl StrPrelude for str {
|
|||
fn slice_to(&self, end: uint) -> &str {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(end) {
|
||||
unsafe { raw::slice_unchecked(self, 0, end) }
|
||||
unsafe { self.slice_unchecked(0, end) }
|
||||
} else {
|
||||
slice_error_fail(self, 0, end)
|
||||
}
|
||||
|
|
@ -2057,10 +2098,18 @@ impl StrPrelude for str {
|
|||
match (begin_byte, end_byte) {
|
||||
(None, _) => panic!("slice_chars: `begin` is beyond end of string"),
|
||||
(_, None) => panic!("slice_chars: `end` is beyond end of string"),
|
||||
(Some(a), Some(b)) => unsafe { raw::slice_bytes(self, a, b) }
|
||||
(Some(a), Some(b)) => unsafe { self.slice_unchecked(a, b) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn slice_unchecked(&self, begin: uint, end: uint) -> &str {
|
||||
mem::transmute(Slice {
|
||||
data: self.as_ptr().offset(begin as int),
|
||||
len: end - begin,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn starts_with(&self, needle: &str) -> bool {
|
||||
let n = needle.len();
|
||||
|
|
@ -2077,13 +2126,13 @@ impl StrPrelude for str {
|
|||
fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
|
||||
let cur = match self.find(|c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(i) => unsafe { raw::slice_bytes(self, i, self.len()) }
|
||||
Some(i) => unsafe { self.slice_unchecked(i, self.len()) }
|
||||
};
|
||||
match cur.rfind(|c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(i) => {
|
||||
let right = cur.char_range_at(i).next;
|
||||
unsafe { raw::slice_bytes(cur, 0, right) }
|
||||
unsafe { cur.slice_unchecked(0, right) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2092,7 +2141,7 @@ impl StrPrelude for str {
|
|||
fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
|
||||
match self.find(|c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(first) => unsafe { raw::slice_bytes(self, first, self.len()) }
|
||||
Some(first) => unsafe { self.slice_unchecked(first, self.len()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2102,7 +2151,7 @@ impl StrPrelude for str {
|
|||
None => "",
|
||||
Some(last) => {
|
||||
let next = self.char_range_at(last).next;
|
||||
unsafe { raw::slice_bytes(self, 0u, next) }
|
||||
unsafe { self.slice_unchecked(0u, next) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2223,7 +2272,7 @@ impl StrPrelude for str {
|
|||
None
|
||||
} else {
|
||||
let CharRange {ch, next} = self.char_range_at(0u);
|
||||
let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
|
||||
let next_s = unsafe { self.slice_unchecked(next, self.len()) };
|
||||
Some((ch, next_s))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue