about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-23 05:46:52 +0000
committerbors <bors@rust-lang.org>2014-11-23 05:46:52 +0000
commit641e2a110de4bb1b2c2b596ef1168ae7865aa529 (patch)
treee3bcf593519b1aa31df2d79373079f1ada8e0d39 /src
parent529f8bcd8b03f1bcff46c31c682ce9274abff86d (diff)
parent8ca27a633ed393438a12bbf074b4f2e6063baa6f (diff)
downloadrust-641e2a110de4bb1b2c2b596ef1168ae7865aa529.tar.gz
rust-641e2a110de4bb1b2c2b596ef1168ae7865aa529.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/libcollections/slice.rs2
-rw-r--r--src/libcollections/str.rs16
-rw-r--r--src/libcollections/string.rs76
-rw-r--r--src/libcollections/vec.rs28
-rw-r--r--src/libcore/slice.rs50
-rw-r--r--src/libcore/str.rs103
-rw-r--r--src/librand/isaac.rs18
-rw-r--r--src/librustc/metadata/loader.rs28
-rw-r--r--src/librustdoc/html/markdown.rs137
-rw-r--r--src/librustrt/args.rs10
-rw-r--r--src/libserialize/base64.rs9
-rw-r--r--src/libserialize/hex.rs5
-rw-r--r--src/libstd/ascii.rs14
-rw-r--r--src/libstd/os.rs14
-rw-r--r--src/libstd/sys/unix/os.rs2
15 files changed, 304 insertions, 208 deletions
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index c3a248ce318..d9a5f3d66f9 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 0fe40081a46..ef219ec4c96 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -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.
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index e6698542df2..dd9dad9a42f 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<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)
     }
 }
 
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 0777a1a128f..acb91f3edcf 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -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)
     }
 }
 
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 7a3e06e7eb4..754da272c24 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -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);
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 28d0dff25d2..3b2a7c62312 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) }
@@ -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,11 +2098,19 @@ 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();
         self.len() >= n && needle.as_bytes() == self.as_bytes()[..n]
@@ -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))
         }
     }
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index 49d60a98b64..02dd53e4214 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<R: Rng>(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<R: Rng>(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 269c15e7d81..bd0446dd67f 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<MetadataBlo
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
             let mut name_buf = ptr::null();
             let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
-            let name = string::raw::from_buf_len(name_buf as *const u8,
-                                              name_len as uint);
+            let name = String::from_raw_buf_len(name_buf as *const u8,
+                                                name_len as uint);
             debug!("get_metadata_section: name {}", name);
             if read_meta_section_name(is_osx).as_slice() == name.as_slice() {
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
                 let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
-                let mut found =
-                    Err(format!("metadata not found: '{}'", filename.display()));
                 let cvbuf: *const u8 = cbuf as *const u8;
                 let vlen = encoder::metadata_encoding_version.len();
                 debug!("checking {} bytes of metadata-version stamp",
                        vlen);
                 let minsz = cmp::min(vlen, csz);
-                let version_ok = slice::raw::buf_as_slice(cvbuf, minsz,
-                    |buf0| buf0 == encoder::metadata_encoding_version);
+                let buf0 = slice::from_raw_buf(&cvbuf, minsz);
+                let version_ok = buf0 == encoder::metadata_encoding_version;
                 if !version_ok {
                     return Err((format!("incompatible metadata version found: '{}'",
                                         filename.display())));
@@ -764,19 +761,10 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
                 let cvbuf1 = cvbuf.offset(vlen as int);
                 debug!("inflating {} bytes of compressed metadata",
                        csz - vlen);
-                slice::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
-                    match flate::inflate_bytes(bytes) {
-                        Some(inflated) => 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 9dacee1652a..043d7b9f1a4 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::<Vec<&str>>().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::<Vec<&str>>().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!("<span id='rust-example-raw-{}' \
-                                             class='rusttest'>{}</span>",
-                                           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::<Vec<&str>>().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::<Vec<&str>>().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!("<span id='rust-example-raw-{}' \
+                                         class='rusttest'>{}</span>",
+                                       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::<Vec<&str>>().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::<Vec<&str>>().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 5eecc0a53e0..d94f731e75c 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<u8>> {
         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 9b1e285431f..41feee8257f 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<u8>` into a string with characters corresponding to those values.
+     * You can use the `String::from_utf8` function to turn a `Vec<u8>` into a
+     * string with characters corresponding to those values.
      *
      * # Example
      *
diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs
index bd49da7667a..78859d6778d 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<u8>` into a string with characters corresponding to those values.
      *
      * # Example
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 933794cb5a4..47189ba84ed 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.
@@ -331,9 +331,7 @@ impl AsciiStr for [Ascii] {
 impl IntoString for Vec<Ascii> {
     #[inline]
     fn into_string(self) -> String {
-        unsafe {
-            string::raw::from_utf8(self.into_bytes())
-        }
+        unsafe { String::from_utf8_unchecked(self.into_bytes()) }
     }
 }
 
@@ -394,13 +392,13 @@ impl AsciiExt<String> for str {
     #[inline]
     fn to_ascii_upper(&self) -> String {
         // Vec<u8>::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<u8>::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]
@@ -413,13 +411,13 @@ impl OwnedAsciiExt for String {
     #[inline]
     fn into_ascii_upper(self) -> String {
         // Vec<u8>::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<u8>::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 d7ba4877086..b3591cd6408 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -248,7 +248,7 @@ pub fn env_as_bytes() -> Vec<(Vec<u8>,Vec<u8>)> {
     unsafe {
         #[cfg(windows)]
         unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
-            use slice::raw;
+            use slice;
 
             use libc::funcs::extra::kernel32::{
                 GetEnvironmentStringsW,
@@ -281,9 +281,9 @@ pub fn env_as_bytes() -> Vec<(Vec<u8>,Vec<u8>)> {
                 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<String> {
         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 4e495f043bc..d951977fa59 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)
     }
 }