From 8ca27a633ed393438a12bbf074b4f2e6063baa6f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 20 Nov 2014 10:11:15 -0800 Subject: [PATCH] std: Align `raw` modules with unsafe conventions 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::with_raw_buf * slice::raw::mut_buf_as_slice => slice::with_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 --- src/libcollections/slice.rs | 2 +- src/libcollections/str.rs | 16 +--- src/libcollections/string.rs | 76 +++++++++++++----- src/libcollections/vec.rs | 28 ++++--- src/libcore/slice.rs | 50 +++++++++++- src/libcore/str.rs | 103 +++++++++++++++++------- src/librand/isaac.rs | 18 ++--- src/librustc/metadata/loader.rs | 28 ++----- src/librustdoc/html/markdown.rs | 137 +++++++++++++++----------------- src/librustrt/args.rs | 10 +-- src/libserialize/base64.rs | 9 +-- src/libserialize/hex.rs | 5 +- src/libstd/ascii.rs | 14 ++-- src/libstd/os.rs | 14 ++-- src/libstd/sys/unix/os.rs | 2 +- 15 files changed, 304 insertions(+), 208 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 5e341ba8b04d3..44282e89291b2 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -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 diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index aaa7da312f29a..8058fcf585205 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -79,6 +79,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 @@ -392,11 +393,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 } @@ -669,16 +670,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. diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index e6698542df238..dd9dad9a42f7d 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -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`; + /// * 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) -> String { + String { vec: bytes } + } + /// Return the underlying byte buffer, encoded as UTF-8. /// /// # Example @@ -823,12 +869,8 @@ impl 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`; /// * 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) -> String { - String { vec: bytes } + String::from_utf8_unchecked(bytes) } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 7111a0776307a..a88b2294853bf 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -234,12 +234,27 @@ impl Vec { /// } /// } /// ``` - #[experimental] + #[unstable = "needs finalization"] pub unsafe fn from_raw_parts(ptr: *mut T, length: uint, capacity: uint) -> Vec { 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 { + 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` @@ -1366,23 +1381,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(ptr: *const T, elts: uint) -> Vec { - 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) } } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 7923c46717e66..4caed722d90f8 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1547,15 +1547,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; @@ -1567,6 +1607,7 @@ pub mod raw { * not bytes). */ #[inline] + #[deprecated = "renamed to slice::from_raw_buf"] pub unsafe fn buf_as_slice(p: *const T, len: uint, f: |v: &[T]| -> U) -> U { f(transmute(Slice { @@ -1580,6 +1621,7 @@ pub mod raw { * not bytes). */ #[inline] + #[deprecated = "renamed to slice::from_raw_mut_buf"] pub unsafe fn mut_buf_as_slice( p: *mut T, @@ -1598,6 +1640,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(slice: &mut Slice) -> Option<*const T> { if slice.len == 0 { return None; } let head: *const T = slice.data; @@ -1611,7 +1654,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(slice: &mut Slice) -> Option<*const T> { if slice.len == 0 { return None; } let tail: *const T = slice.data.offset((slice.len - 1) as int); diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 24f26b15f27ac..223d4584031bf 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -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) } @@ -1090,8 +1122,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; @@ -1099,13 +1131,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; @@ -1128,10 +1162,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. @@ -1140,11 +1175,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) } } @@ -1544,6 +1577,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 @@ -1991,7 +2032,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) } @@ -2001,7 +2042,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()) } @@ -2011,7 +2052,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) } @@ -2036,10 +2077,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(); @@ -2056,13 +2105,13 @@ impl StrPrelude for str { fn trim_chars(&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) } } } } @@ -2071,7 +2120,7 @@ impl StrPrelude for str { fn trim_left_chars(&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()) } } } @@ -2081,7 +2130,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) } } } } @@ -2202,7 +2251,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)) } } diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 49d60a98b6496..02dd53e4214ba 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -12,7 +12,7 @@ use core::prelude::*; use core::iter::{range_step, Repeat}; -use core::slice::raw; +use core::slice; use {Rng, SeedableRng, Rand}; @@ -234,12 +234,10 @@ impl Rand for IsaacRng { fn rand(other: &mut R) -> IsaacRng { let mut ret = EMPTY; unsafe { - let ptr = ret.rsl.as_mut_ptr(); + let ptr = ret.rsl.as_mut_ptr() as *mut u8; - raw::mut_buf_as_slice(ptr as *mut u8, - (RAND_SIZE*4) as uint, |slice| { - other.fill_bytes(slice); - }) + let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE * 4) as uint); + other.fill_bytes(slice); } ret.cnt = 0; ret.a = 0; @@ -469,12 +467,10 @@ impl Rand for Isaac64Rng { fn rand(other: &mut R) -> Isaac64Rng { let mut ret = EMPTY_64; unsafe { - let ptr = ret.rsl.as_mut_ptr(); + let ptr = ret.rsl.as_mut_ptr() as *mut u8; - raw::mut_buf_as_slice(ptr as *mut u8, - (RAND_SIZE_64*8) as uint, |slice| { - other.fill_bytes(slice); - }) + let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE_64 * 8) as uint); + other.fill_bytes(slice); } ret.cnt = 0; ret.a = 0; diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 269c15e7d81a4..bd0446dd67ff2 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -234,7 +234,6 @@ use std::io::fs::PathExtensions; use std::io; use std::ptr; use std::slice; -use std::string; use std::time::Duration; use flate; @@ -741,21 +740,19 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result Result found = Ok(MetadataVec(inflated)), - None => { - found = - Err(format!("failed to decompress \ - metadata for: '{}'", - filename.display())) - } - } - }); - if found.is_ok() { - return found; + let bytes = slice::from_raw_buf(&cvbuf1, csz-vlen); + match flate::inflate_bytes(bytes) { + Some(inflated) => return Ok(MetadataVec(inflated)), + None => {} } } llvm::LLVMMoveToNextSection(si.llsi); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 9dacee1652a4a..043d7b9f1a462 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -32,7 +32,6 @@ use std::cell::{RefCell, Cell}; use std::fmt; use std::slice; use std::str; -use std::string; use std::collections::HashMap; use html::toc::TocBuilder; @@ -160,54 +159,52 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { let opaque = opaque as *mut hoedown_html_renderer_state; let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque); - slice::raw::buf_as_slice((*orig_text).data, (*orig_text).size as uint, - |text| { - let origtext = str::from_utf8(text).unwrap(); - debug!("docblock: ==============\n{}\n=======", text); - let rendered = if lang.is_null() { - false + let text = slice::from_raw_buf(&(*orig_text).data, + (*orig_text).size as uint); + let origtext = str::from_utf8(text).unwrap(); + debug!("docblock: ==============\n{}\n=======", text); + let rendered = if lang.is_null() { + false + } else { + let rlang = slice::from_raw_buf(&(*lang).data, + (*lang).size as uint); + let rlang = str::from_utf8(rlang).unwrap(); + if LangString::parse(rlang).notrust { + (my_opaque.dfltblk)(ob, orig_text, lang, + opaque as *mut libc::c_void); + true } else { - slice::raw::buf_as_slice((*lang).data, - (*lang).size as uint, |rlang| { - let rlang = str::from_utf8(rlang).unwrap(); - if LangString::parse(rlang).notrust { - (my_opaque.dfltblk)(ob, orig_text, lang, - opaque as *mut libc::c_void); - true - } else { - false - } - }) - }; - - let mut lines = origtext.lines().filter(|l| { - stripped_filtered_line(*l).is_none() - }); - let text = lines.collect::>().connect("\n"); - if !rendered { - let mut s = String::new(); - let id = playground_krate.get().map(|krate| { - let idx = test_idx.get().unwrap(); - let i = idx.get(); - idx.set(i + 1); - - let test = origtext.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }).collect::>().connect("\n"); - let krate = krate.as_ref().map(|s| s.as_slice()); - let test = test::maketest(test.as_slice(), krate, false, false); - s.push_str(format!("{}", - i, Escape(test.as_slice())).as_slice()); - format!("rust-example-rendered-{}", i) - }); - let id = id.as_ref().map(|a| a.as_slice()); - s.push_str(highlight::highlight(text.as_slice(), None, id) - .as_slice()); - let output = s.to_c_str(); - hoedown_buffer_puts(ob, output.as_ptr()); + false } - }) + }; + + let mut lines = origtext.lines().filter(|l| { + stripped_filtered_line(*l).is_none() + }); + let text = lines.collect::>().connect("\n"); + if !rendered { + let mut s = String::new(); + let id = playground_krate.get().map(|krate| { + let idx = test_idx.get().unwrap(); + let i = idx.get(); + idx.set(i + 1); + + let test = origtext.lines().map(|l| { + stripped_filtered_line(l).unwrap_or(l) + }).collect::>().connect("\n"); + let krate = krate.as_ref().map(|s| s.as_slice()); + let test = test::maketest(test.as_slice(), krate, false, false); + s.push_str(format!("{}", + i, Escape(test.as_slice())).as_slice()); + format!("rust-example-rendered-{}", i) + }); + let id = id.as_ref().map(|a| a.as_slice()); + s.push_str(highlight::highlight(text.as_slice(), None, id) + .as_slice()); + let output = s.to_c_str(); + hoedown_buffer_puts(ob, output.as_ptr()); + } } } @@ -221,7 +218,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { "".to_string() } else { unsafe { - string::raw::from_buf_len((*text).data, (*text).size as uint) + String::from_raw_buf_len((*text).data, (*text).size as uint) } }; @@ -296,9 +293,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { }; if ret.is_ok() { - ret = slice::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| { - w.write(buf) - }); + let buf = slice::from_raw_buf(&(*ob).data, (*ob).size as uint); + ret = w.write(buf); } hoedown_buffer_free(ob); ret @@ -315,25 +311,23 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { let block_info = if lang.is_null() { LangString::all_false() } else { - slice::raw::buf_as_slice((*lang).data, - (*lang).size as uint, |lang| { - let s = str::from_utf8(lang).unwrap(); - LangString::parse(s) - }) + let lang = slice::from_raw_buf(&(*lang).data, + (*lang).size as uint); + let s = str::from_utf8(lang).unwrap(); + LangString::parse(s) }; if block_info.notrust { return } - slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| { - let opaque = opaque as *mut hoedown_html_renderer_state; - let tests = &mut *((*opaque).opaque as *mut ::test::Collector); - let text = str::from_utf8(text).unwrap(); - let mut lines = text.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }); - let text = lines.collect::>().connect("\n"); - tests.add_test(text.to_string(), - block_info.should_fail, block_info.no_run, - block_info.ignore, block_info.test_harness); - }) + let text = slice::from_raw_buf(&(*text).data, (*text).size as uint); + let opaque = opaque as *mut hoedown_html_renderer_state; + let tests = &mut *((*opaque).opaque as *mut ::test::Collector); + let text = str::from_utf8(text).unwrap(); + let mut lines = text.lines().map(|l| { + stripped_filtered_line(l).unwrap_or(l) + }); + let text = lines.collect::>().connect("\n"); + tests.add_test(text.to_string(), + block_info.should_fail, block_info.no_run, + block_info.ignore, block_info.test_harness); } } @@ -346,10 +340,9 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { if text.is_null() { tests.register_header("", level as u32); } else { - slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| { - let text = str::from_utf8(text).unwrap(); - tests.register_header(text, level as u32); - }) + let text = slice::from_raw_buf(&(*text).data, (*text).size as uint); + let text = str::from_utf8(text).unwrap(); + tests.register_header(text, level as u32); } } } diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs index 5eecc0a53e048..d94f731e75c64 100644 --- a/src/librustrt/args.rs +++ b/src/librustrt/args.rs @@ -47,10 +47,9 @@ mod imp { use core::prelude::*; use alloc::boxed::Box; - use collections::slice::CloneSliceAllocPrelude; use collections::vec::Vec; + use collections::string::String; use core::mem; - use core::slice; use mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; @@ -103,12 +102,7 @@ mod imp { unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec> { Vec::from_fn(argc as uint, |i| { - let base = *argv.offset(i as int); - let mut len = 0; - while *base.offset(len) != 0 { len += 1; } - slice::raw::buf_as_slice(base, len as uint, |slice| { - slice.to_vec() - }) + String::from_raw_buf(*argv.offset(i as int)).into_bytes() }) } diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index 9b1e285431f6a..41feee8257f9c 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -16,7 +16,6 @@ pub use self::FromBase64Error::*; pub use self::CharacterSet::*; use std::fmt; -use std::string; use std::error; /// Available encoding character sets @@ -152,9 +151,7 @@ impl ToBase64 for [u8] { _ => panic!("Algebra is broken, please alert the math police") } - unsafe { - string::raw::from_utf8(v) - } + unsafe { String::from_utf8_unchecked(v) } } } @@ -201,8 +198,8 @@ impl FromBase64 for str { * Convert any base64 encoded string (literal, `@`, `&`, or `~`) * to the byte values it encodes. * - * You can use the `String::from_utf8` function in `std::string` to turn a - * `Vec` into a string with characters corresponding to those values. + * You can use the `String::from_utf8` function to turn a `Vec` into a + * string with characters corresponding to those values. * * # Example * diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index bd49da7667a9b..78859d6778d70 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -15,7 +15,6 @@ pub use self::FromHexError::*; use std::fmt; -use std::string; use std::error; /// A trait for converting a value to hexadecimal encoding @@ -51,7 +50,7 @@ impl ToHex for [u8] { } unsafe { - string::raw::from_utf8(v) + String::from_utf8_unchecked(v) } } } @@ -100,7 +99,7 @@ impl FromHex for str { * Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`) * to the byte values it encodes. * - * You can use the `String::from_utf8` function in `std::string` to turn a + * You can use the `String::from_utf8` function to turn a * `Vec` into a string with characters corresponding to those values. * * # Example diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 923349b1bf740..380cbd43e4f57 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -21,7 +21,7 @@ use mem; use option::{Option, Some, None}; use slice::{SlicePrelude, AsSlice}; use str::{Str, StrPrelude}; -use string::{mod, String, IntoString}; +use string::{String, IntoString}; use vec::Vec; /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero. @@ -328,9 +328,7 @@ impl AsciiStr for [Ascii] { impl IntoString for Vec { #[inline] fn into_string(self) -> String { - unsafe { - string::raw::from_utf8(self.into_bytes()) - } + unsafe { String::from_utf8_unchecked(self.into_bytes()) } } } @@ -391,13 +389,13 @@ impl AsciiExt for str { #[inline] fn to_ascii_upper(&self) -> String { // Vec::to_ascii_upper() preserves the UTF-8 invariant. - unsafe { string::raw::from_utf8(self.as_bytes().to_ascii_upper()) } + unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_upper()) } } #[inline] fn to_ascii_lower(&self) -> String { // Vec::to_ascii_lower() preserves the UTF-8 invariant. - unsafe { string::raw::from_utf8(self.as_bytes().to_ascii_lower()) } + unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_lower()) } } #[inline] @@ -410,13 +408,13 @@ impl OwnedAsciiExt for String { #[inline] fn into_ascii_upper(self) -> String { // Vec::into_ascii_upper() preserves the UTF-8 invariant. - unsafe { string::raw::from_utf8(self.into_bytes().into_ascii_upper()) } + unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_upper()) } } #[inline] fn into_ascii_lower(self) -> String { // Vec::into_ascii_lower() preserves the UTF-8 invariant. - unsafe { string::raw::from_utf8(self.into_bytes().into_ascii_lower()) } + unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_lower()) } } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 68ddabfd48f27..1e659aea4f261 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -248,7 +248,7 @@ pub fn env_as_bytes() -> Vec<(Vec,Vec)> { unsafe { #[cfg(windows)] unsafe fn get_env_pairs() -> Vec> { - use slice::raw; + use slice; use libc::funcs::extra::kernel32::{ GetEnvironmentStringsW, @@ -281,9 +281,9 @@ pub fn env_as_bytes() -> Vec<(Vec,Vec)> { while *(p as *const _).offset(len) != 0 { len += 1; } - raw::buf_as_slice(p, len as uint, |s| { - result.push(String::from_utf16_lossy(s).into_bytes()); - }); + let p = p as *const u16; + let s = slice::from_raw_buf(&p, len as uint); + result.push(String::from_utf16_lossy(s).into_bytes()); i += len as int + 1; } FreeEnvironmentStringsW(ch); @@ -1071,9 +1071,9 @@ fn real_args() -> Vec { while *ptr.offset(len as int) != 0 { len += 1; } // Push it onto the list. - let opt_s = slice::raw::buf_as_slice(ptr as *const _, len, |buf| { - String::from_utf16(::str::truncate_utf16_at_nul(buf)) - }); + let ptr = ptr as *const u16; + let buf = slice::from_raw_buf(&ptr, len); + let opt_s = String::from_utf16(::str::truncate_utf16_at_nul(buf)); opt_s.expect("CommandLineToArgvW returned invalid UTF-16") }); diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 4e495f043bc63..d951977fa5943 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -98,7 +98,7 @@ pub fn error_string(errno: i32) -> String { panic!("strerror_r failure"); } - ::string::raw::from_buf(p as *const u8) + String::from_raw_buf(p as *const u8) } }