about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-23 02:41:48 +0000
committerbors <bors@rust-lang.org>2014-12-23 02:41:48 +0000
commit62fb41c32bd97c4e9bc286a1db5d7126a06b8b91 (patch)
treefc1c7ab2bf1a29879d45235acaf0126ceae4d107 /src/libstd
parent2f3cff6956d56048ef7afb6d33e17cbdb2dcf038 (diff)
parent3583d613b9c81855feb067aeeebb525cf8a4184c (diff)
downloadrust-62fb41c32bd97c4e9bc286a1db5d7126a06b8b91.tar.gz
rust-62fb41c32bd97c4e9bc286a1db5d7126a06b8b91.zip
auto merge of #20145 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ascii.rs2
-rw-r--r--src/libstd/c_str.rs2
-rw-r--r--src/libstd/collections/hash/map.rs28
-rw-r--r--src/libstd/collections/hash/set.rs126
-rw-r--r--src/libstd/collections/hash/table.rs16
-rw-r--r--src/libstd/dynamic_lib.rs2
-rw-r--r--src/libstd/error.rs18
-rw-r--r--src/libstd/failure.rs2
-rw-r--r--src/libstd/io/mod.rs7
-rw-r--r--src/libstd/io/net/ip.rs2
-rw-r--r--src/libstd/io/process.rs4
-rw-r--r--src/libstd/io/stdio.rs2
-rw-r--r--src/libstd/num/strconv.rs2
-rw-r--r--src/libstd/os.rs12
-rw-r--r--src/libstd/path/mod.rs19
-rw-r--r--src/libstd/path/posix.rs7
-rw-r--r--src/libstd/path/windows.rs162
-rw-r--r--src/libstd/prelude.rs4
-rw-r--r--src/libstd/rt/backtrace.rs3
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/unwind.rs2
-rw-r--r--src/libstd/rt/util.rs23
-rw-r--r--src/libstd/sys/common/backtrace.rs11
-rw-r--r--src/libstd/sys/unix/os.rs2
-rw-r--r--src/libstd/sys/windows/backtrace.rs2
-rw-r--r--src/libstd/sys/windows/fs.rs3
-rw-r--r--src/libstd/sys/windows/os.rs43
-rw-r--r--src/libstd/sys/windows/process.rs2
-rw-r--r--src/libstd/sys/windows/tty.rs2
-rw-r--r--src/libstd/thread_local/mod.rs24
30 files changed, 367 insertions, 169 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 08b17f25e29..2c49beca98d 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -23,7 +23,7 @@ use ops::FnMut;
 use option::Option;
 use option::Option::{Some, None};
 use slice::{SliceExt, AsSlice};
-use str::{Str, StrPrelude};
+use str::{Str, StrExt};
 use string::{String, IntoString};
 use vec::Vec;
 
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index f1c8e8950a2..fb44961017f 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -228,7 +228,7 @@ impl CString {
     #[inline]
     pub fn as_str<'a>(&'a self) -> Option<&'a str> {
         let buf = self.as_bytes_no_nul();
-        str::from_utf8(buf)
+        str::from_utf8(buf).ok()
     }
 
     /// Return a CString iterator.
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 8149864afd4..d749cd77cef 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -838,8 +838,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn keys(&self) -> Keys<K, V> {
+    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
 
         Keys { inner: self.iter().map(first) }
     }
@@ -862,8 +863,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn values(&self) -> Values<K, V> {
+    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
         fn second<A, B>((_, b): (A, B)) -> B { b }
+        let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
 
         Values { inner: self.iter().map(second) }
     }
@@ -914,8 +916,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn iter_mut(&mut self) -> MutEntries<K, V> {
-        MutEntries { inner: self.table.iter_mut() }
+    pub fn iter_mut(&mut self) -> IterMut<K, V> {
+        IterMut { inner: self.table.iter_mut() }
     }
 
     /// Creates a consuming iterator, that is, one that moves each key-value
@@ -936,10 +938,11 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// let vec: Vec<(&str, int)> = map.into_iter().collect();
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn into_iter(self) -> MoveEntries<K, V> {
+    pub fn into_iter(self) -> IntoIter<K, V> {
         fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
 
-        MoveEntries {
+        IntoIter {
             inner: self.table.into_iter().map(last_two)
         }
     }
@@ -1007,6 +1010,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn drain(&mut self) -> Drain<K, V> {
         fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
 
         Drain {
             inner: self.table.drain().map(last_two),
@@ -1306,16 +1310,16 @@ pub struct Entries<'a, K: 'a, V: 'a> {
 }
 
 /// HashMap mutable values iterator
-pub struct MutEntries<'a, K: 'a, V: 'a> {
-    inner: table::MutEntries<'a, K, V>
+pub struct IterMut<'a, K: 'a, V: 'a> {
+    inner: table::IterMut<'a, K, V>
 }
 
 /// HashMap move iterator
-pub struct MoveEntries<K, V> {
+pub struct IntoIter<K, V> {
     inner: iter::Map<
         (SafeHash, K, V),
         (K, V),
-        table::MoveEntries<K, V>,
+        table::IntoIter<K, V>,
         fn((SafeHash, K, V)) -> (K, V),
     >
 }
@@ -1374,12 +1378,12 @@ impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
     #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
-impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
+impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for IterMut<'a, K, V> {
     #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
-impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
+impl<K, V> Iterator<(K, V)> for IntoIter<K, V> {
     #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index f587669d3da..6d83d5510b3 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -11,20 +11,19 @@
 // ignore-lexer-test FIXME #15883
 
 use borrow::BorrowFrom;
+use clone::Clone;
 use cmp::{Eq, Equiv, PartialEq};
 use core::kinds::Sized;
 use default::Default;
 use fmt::Show;
 use fmt;
 use hash::{Hash, Hasher, RandomSipHasher};
-use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend};
+use iter::{Iterator, IteratorExt, IteratorCloneExt, FromIterator, Map, Chain, Extend};
+use ops::{BitOr, BitAnd, BitXor, Sub};
 use option::Option::{Some, None, mod};
 use result::Result::{Ok, Err};
 
-use super::map::{mod, HashMap, MoveEntries, Keys, INITIAL_CAPACITY};
-
-// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub
-
+use super::map::{mod, HashMap, Keys, INITIAL_CAPACITY};
 
 // Future Optimization (FIXME!)
 // =============================
@@ -277,6 +276,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(self) -> IntoIter<T> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first;
 
         IntoIter { iter: self.map.into_iter().map(first) }
     }
@@ -419,6 +419,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn drain(&mut self) -> Drain<T> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first; // coerce to fn pointer
+
         Drain { iter: self.map.drain().map(first) }
     }
 
@@ -618,6 +620,118 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
     }
 }
 
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitOr<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the union of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &a | &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 3, 4, 5];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitor(self, rhs: &HashSet<T, H>) -> HashSet<T, H> {
+        self.union(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitAnd<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &a & &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [2, 3];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitand(self, rhs: &HashSet<T, H>) -> HashSet<T, H> {
+        self.intersection(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitXor<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &a ^ &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 4, 5];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitxor(self, rhs: &HashSet<T, H>) -> HashSet<T, H> {
+        self.symmetric_difference(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+Sub<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &a - &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn sub(self, rhs: &HashSet<T, H>) -> HashSet<T, H> {
+        self.difference(rhs).cloned().collect()
+    }
+}
+
 /// HashSet iterator
 pub struct Iter<'a, K: 'a> {
     iter: Keys<'a, K, ()>
@@ -625,7 +739,7 @@ pub struct Iter<'a, K: 'a> {
 
 /// HashSet move iterator
 pub struct IntoIter<K> {
-    iter: Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ())) -> K>
+    iter: Map<(K, ()), K, map::IntoIter<K, ()>, fn((K, ())) -> K>
 }
 
 /// HashSet drain iterator
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index ce7dbd8ea5e..8f2152c5a9d 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -664,17 +664,17 @@ impl<K, V> RawTable<K, V> {
         }
     }
 
-    pub fn iter_mut(&mut self) -> MutEntries<K, V> {
-        MutEntries {
+    pub fn iter_mut(&mut self) -> IterMut<K, V> {
+        IterMut {
             iter: self.raw_buckets(),
             elems_left: self.size(),
         }
     }
 
-    pub fn into_iter(self) -> MoveEntries<K, V> {
+    pub fn into_iter(self) -> IntoIter<K, V> {
         let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
-        MoveEntries {
+        IntoIter {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
@@ -776,13 +776,13 @@ pub struct Entries<'a, K: 'a, V: 'a> {
 }
 
 /// Iterator over mutable references to entries in a table.
-pub struct MutEntries<'a, K: 'a, V: 'a> {
+pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
     elems_left: uint,
 }
 
 /// Iterator over the entries in a table, consuming the table.
-pub struct MoveEntries<K, V> {
+pub struct IntoIter<K, V> {
     table: RawTable<K, V>,
     iter: RawBuckets<'static, K, V>
 }
@@ -809,7 +809,7 @@ impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
     }
 }
 
-impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
+impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for IterMut<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
         self.iter.next().map(|bucket| {
             self.elems_left -= 1;
@@ -825,7 +825,7 @@ impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
     }
 }
 
-impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
+impl<K, V> Iterator<(SafeHash, K, V)> for IntoIter<K, V> {
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
         self.iter.next().map(|bucket| {
             self.table.size -= 1;
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 4d8c7d67b8c..368abe7cb12 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -280,7 +280,7 @@ pub mod dl {
     use result::Result;
     use result::Result::{Ok, Err};
     use slice::SliceExt;
-    use str::StrPrelude;
+    use str::StrExt;
     use str;
     use string::String;
     use vec::Vec;
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 9ad2655f6e9..cd7d9aacc90 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -78,10 +78,9 @@
 //! }
 //! ```
 
-use option::Option;
-use option::Option::None;
-use kinds::Send;
-use string::String;
+use prelude::*;
+
+use str::Utf8Error;
 
 /// Base functionality for all errors in Rust.
 pub trait Error: Send {
@@ -107,3 +106,14 @@ impl<E> FromError<E> for E {
         err
     }
 }
+
+impl Error for Utf8Error {
+    fn description(&self) -> &str {
+        match *self {
+            Utf8Error::TooShort => "invalid utf-8: not enough bytes",
+            Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
+        }
+    }
+
+    fn detail(&self) -> Option<String> { Some(self.to_string()) }
+}
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index 8e1e3dc4af9..7010eae6dba 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -41,7 +41,7 @@ pub fn on_fail(obj: &(Any+Send), file: &'static str, line: uint) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
-            Some(s) => s.as_slice(),
+            Some(s) => s[],
             None => "Box<Any>",
         }
     };
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index dbf61b132e0..233ad781093 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -242,10 +242,11 @@ use result::Result;
 use result::Result::{Ok, Err};
 use sys;
 use slice::SliceExt;
-use str::StrPrelude;
+use str::StrExt;
 use str;
 use string::String;
 use uint;
+use unicode;
 use unicode::char::UnicodeChar;
 use vec::Vec;
 
@@ -1505,7 +1506,7 @@ pub trait Buffer: Reader {
     /// valid utf-8 encoded codepoint as the next few bytes in the stream.
     fn read_char(&mut self) -> IoResult<char> {
         let first_byte = try!(self.read_byte());
-        let width = str::utf8_char_width(first_byte);
+        let width = unicode::str::utf8_char_width(first_byte);
         if width == 1 { return Ok(first_byte as char) }
         if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
         let mut buf = [first_byte, 0, 0, 0];
@@ -1519,7 +1520,7 @@ pub trait Buffer: Reader {
                 }
             }
         }
-        match str::from_utf8(buf[..width]) {
+        match str::from_utf8(buf[..width]).ok() {
             Some(s) => Ok(s.char_at(0)),
             None => Err(standard_error(InvalidInput))
         }
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 71776b6c46a..89a649d55bd 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -25,8 +25,8 @@ use ops::FnOnce;
 use option::Option;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
-use str::{FromStr, StrPrelude};
 use slice::{CloneSliceExt, SliceExt};
+use str::{FromStr, StrExt};
 use vec::Vec;
 
 pub type Port = u16;
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 9da1117f227..4a0a3936424 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -1082,7 +1082,7 @@ mod tests {
 
         let prog = env_cmd().env_set_all(new_env.as_slice()).spawn().unwrap();
         let result = prog.wait_with_output().unwrap();
-        let output = String::from_utf8_lossy(result.output.as_slice()).into_string();
+        let output = String::from_utf8_lossy(result.output.as_slice()).to_string();
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
@@ -1092,7 +1092,7 @@ mod tests {
     fn test_add_to_env() {
         let prog = env_cmd().env("RUN_TEST_NEW_ENV", "123").spawn().unwrap();
         let result = prog.wait_with_output().unwrap();
-        let output = String::from_utf8_lossy(result.output.as_slice()).into_string();
+        let output = String::from_utf8_lossy(result.output.as_slice()).to_string();
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 36dd5492356..1c5ceaf2450 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -43,7 +43,7 @@ use ops::{Deref, DerefMut, FnOnce};
 use result::Result::{Ok, Err};
 use rt;
 use slice::SliceExt;
-use str::StrPrelude;
+use str::StrExt;
 use string::String;
 use sys::{fs, tty};
 use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index b3e4dd52f89..d6331f3c718 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -20,7 +20,7 @@ use char::{mod, Char};
 use num::{mod, Int, Float, FPNaN, FPInfinite, ToPrimitive};
 use ops::FnMut;
 use slice::{SliceExt, CloneSliceExt};
-use str::StrPrelude;
+use str::StrExt;
 use string::String;
 use vec::Vec;
 
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 258e8964a9f..ceb9a4102f6 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -52,7 +52,7 @@ use result::Result;
 use result::Result::{Err, Ok};
 use slice::{AsSlice, SliceExt};
 use slice::CloneSliceExt;
-use str::{Str, StrPrelude, StrAllocating};
+use str::{Str, StrExt};
 use string::{String, ToString};
 use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use vec::Vec;
@@ -134,8 +134,8 @@ fn with_env_lock<T, F>(f: F) -> T where
 /// ```
 pub fn env() -> Vec<(String,String)> {
     env_as_bytes().into_iter().map(|(k,v)| {
-        let k = String::from_utf8_lossy(k.as_slice()).into_string();
-        let v = String::from_utf8_lossy(v.as_slice()).into_string();
+        let k = String::from_utf8_lossy(k.as_slice()).into_owned();
+        let v = String::from_utf8_lossy(v.as_slice()).into_owned();
         (k,v)
     }).collect()
 }
@@ -185,7 +185,7 @@ pub fn env_as_bytes() -> Vec<(Vec<u8>,Vec<u8>)> {
 /// }
 /// ```
 pub fn getenv(n: &str) -> Option<String> {
-    getenv_as_bytes(n).map(|v| String::from_utf8_lossy(v.as_slice()).into_string())
+    getenv_as_bytes(n).map(|v| String::from_utf8_lossy(v.as_slice()).into_owned())
 }
 
 #[cfg(unix)]
@@ -707,7 +707,7 @@ fn real_args_as_bytes() -> Vec<Vec<u8>> {
 fn real_args() -> Vec<String> {
     real_args_as_bytes().into_iter()
                         .map(|v| {
-                            String::from_utf8_lossy(v.as_slice()).into_string()
+                            String::from_utf8_lossy(v.as_slice()).into_owned()
                         }).collect()
 }
 
@@ -729,7 +729,7 @@ fn real_args() -> Vec<String> {
         // Push it onto the list.
         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));
+        let opt_s = String::from_utf16(sys::os::truncate_utf16_at_nul(buf));
         opt_s.expect("CommandLineToArgvW returned invalid UTF-16")
     });
 
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index ed4bb6ee081..30f3f56bc1c 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -69,7 +69,7 @@ use iter::IteratorExt;
 use option::Option;
 use option::Option::{None, Some};
 use str;
-use str::{CowString, MaybeOwned, Str, StrPrelude};
+use str::{CowString, MaybeOwned, Str, StrExt};
 use string::String;
 use slice::{AsSlice, CloneSliceExt};
 use slice::{PartialEqSliceExt, SliceExt};
@@ -197,7 +197,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn as_str<'a>(&'a self) -> Option<&'a str> {
-        str::from_utf8(self.as_vec())
+        str::from_utf8(self.as_vec()).ok()
     }
 
     /// Returns the path as a byte vector
@@ -293,7 +293,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn dirname_str<'a>(&'a self) -> Option<&'a str> {
-        str::from_utf8(self.dirname())
+        str::from_utf8(self.dirname()).ok()
     }
 
     /// Returns the file component of `self`, as a byte vector.
@@ -327,7 +327,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn filename_str<'a>(&'a self) -> Option<&'a str> {
-        self.filename().and_then(str::from_utf8)
+        self.filename().and_then(|s| str::from_utf8(s).ok())
     }
 
     /// Returns the stem of the filename of `self`, as a byte vector.
@@ -373,7 +373,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn filestem_str<'a>(&'a self) -> Option<&'a str> {
-        self.filestem().and_then(str::from_utf8)
+        self.filestem().and_then(|s| str::from_utf8(s).ok())
     }
 
     /// Returns the extension of the filename of `self`, as an optional byte vector.
@@ -420,7 +420,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn extension_str<'a>(&'a self) -> Option<&'a str> {
-        self.extension().and_then(str::from_utf8)
+        self.extension().and_then(|s| str::from_utf8(s).ok())
     }
 
     /// Replaces the filename portion of the path with the given byte vector or string.
@@ -793,7 +793,7 @@ pub trait BytesContainer for Sized? {
     /// Returns the receiver interpreted as a utf-8 string, if possible
     #[inline]
     fn container_as_str<'a>(&'a self) -> Option<&'a str> {
-        str::from_utf8(self.container_as_bytes())
+        str::from_utf8(self.container_as_bytes()).ok()
     }
     /// Returns whether .container_as_str() is guaranteed to not fail
     // FIXME (#8888): Remove unused arg once ::<for T> works
@@ -870,7 +870,7 @@ impl BytesContainer for String {
     }
     #[inline]
     fn container_as_str(&self) -> Option<&str> {
-        Some(self.as_slice())
+        Some(self[])
     }
     #[inline]
     fn is_str(_: Option<&String>) -> bool { true }
@@ -886,7 +886,7 @@ impl BytesContainer for [u8] {
 impl BytesContainer for Vec<u8> {
     #[inline]
     fn container_as_bytes(&self) -> &[u8] {
-        self.as_slice()
+        self[]
     }
 }
 
@@ -897,6 +897,7 @@ impl BytesContainer for CString {
     }
 }
 
+#[allow(deprecated)]
 impl<'a> BytesContainer for str::MaybeOwned<'a> {
     #[inline]
     fn container_as_bytes<'b>(&'b self) -> &'b [u8] {
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 88907951673..f0a00b421c3 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -390,6 +390,7 @@ impl Path {
         let v = if self.repr[0] == SEP_BYTE {
             self.repr[1..]
         } else { self.repr.as_slice() };
+        let is_sep_byte: fn(&u8) -> bool = is_sep_byte; // coerce to fn ptr
         let mut ret = v.split(is_sep_byte);
         if v.is_empty() {
             // consume the empty "" component
@@ -401,7 +402,11 @@ impl Path {
     /// Returns an iterator that yields each component of the path as Option<&str>.
     /// See components() for details.
     pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
-        self.components().map(str::from_utf8)
+        fn from_utf8(s: &[u8]) -> Option<&str> {
+            str::from_utf8(s).ok()
+        }
+        let f: fn(&[u8]) -> Option<&str> = from_utf8; // coerce to fn ptr
+        self.components().map(f)
     }
 }
 
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index c2c17103554..7d10188c437 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -25,9 +25,9 @@ use iter::{Iterator, IteratorExt, Map};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
-use slice::{AsSlice, SliceExt};
-use str::{CharSplits, FromStr, Str, StrAllocating, StrVector, StrPrelude};
-use string::String;
+use slice::SliceExt;
+use str::{CharSplits, FromStr, StrVector, StrExt};
+use string::{String, ToString};
 use unicode::char::UnicodeChar;
 use vec::Vec;
 
@@ -187,30 +187,30 @@ impl GenericPathUnsafe for Path {
                 s.push_str("..");
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(s);
+                self.update_normalized(s[]);
             }
             None => {
                 self.update_normalized(filename);
             }
-            Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => {
+            Some((_,idxa,end)) if self.repr[idxa..end] == ".." => {
                 let mut s = String::with_capacity(end + 1 + filename.len());
-                s.push_str(self.repr.slice_to(end));
+                s.push_str(self.repr[0..end]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(s);
+                self.update_normalized(s[]);
             }
             Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => {
                 let mut s = String::with_capacity(idxb + filename.len());
-                s.push_str(self.repr.slice_to(idxb));
+                s.push_str(self.repr[0..idxb]);
                 s.push_str(filename);
-                self.update_normalized(s);
+                self.update_normalized(s[]);
             }
             Some((idxb,_,_)) => {
                 let mut s = String::with_capacity(idxb + 1 + filename.len());
-                s.push_str(self.repr.slice_to(idxb));
+                s.push_str(self.repr[0..idxb]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(s);
+                self.update_normalized(s[]);
             }
         }
     }
@@ -229,12 +229,12 @@ impl GenericPathUnsafe for Path {
         let path = path.container_as_str().unwrap();
         fn is_vol_abs(path: &str, prefix: Option<PathPrefix>) -> bool {
             // assume prefix is Some(DiskPrefix)
-            let rest = path.slice_from(prefix_len(prefix));
+            let rest = path[prefix_len(prefix)..];
             !rest.is_empty() && rest.as_bytes()[0].is_ascii() && is_sep(rest.as_bytes()[0] as char)
         }
         fn shares_volume(me: &Path, path: &str) -> bool {
             // path is assumed to have a prefix of Some(DiskPrefix)
-            let repr = me.repr.as_slice();
+            let repr = me.repr[];
             match me.prefix {
                 Some(DiskPrefix) => {
                     repr.as_bytes()[0] == path.as_bytes()[0].to_ascii().to_uppercase().as_byte()
@@ -266,7 +266,7 @@ impl GenericPathUnsafe for Path {
                         else { None };
             let pathlen = path_.as_ref().map_or(path.len(), |p| p.len());
             let mut s = String::with_capacity(me.repr.len() + 1 + pathlen);
-            s.push_str(me.repr.as_slice());
+            s.push_str(me.repr[]);
             let plen = me.prefix_len();
             // if me is "C:" we don't want to add a path separator
             match me.prefix {
@@ -278,9 +278,9 @@ impl GenericPathUnsafe for Path {
             }
             match path_ {
                 None => s.push_str(path),
-                Some(p) => s.push_str(p.as_slice())
+                Some(p) => s.push_str(p[]),
             };
-            me.update_normalized(s)
+            me.update_normalized(s[])
         }
 
         if !path.is_empty() {
@@ -288,7 +288,7 @@ impl GenericPathUnsafe for Path {
             match prefix {
                 Some(DiskPrefix) if !is_vol_abs(path, prefix) && shares_volume(self, path) => {
                     // cwd-relative path, self is on the same volume
-                    append_path(self, path.slice_from(prefix_len(prefix)));
+                    append_path(self, path[prefix_len(prefix)..]);
                 }
                 Some(_) => {
                     // absolute path, or cwd-relative and self is not same volume
@@ -334,7 +334,7 @@ impl GenericPath for Path {
     /// Always returns a `Some` value.
     #[inline]
     fn as_str<'a>(&'a self) -> Option<&'a str> {
-        Some(self.repr.as_slice())
+        Some(self.repr[])
     }
 
     #[inline]
@@ -356,21 +356,17 @@ impl GenericPath for Path {
     /// Always returns a `Some` value.
     fn dirname_str<'a>(&'a self) -> Option<&'a str> {
         Some(match self.sepidx_or_prefix_len() {
-            None if ".." == self.repr => self.repr.as_slice(),
+            None if ".." == self.repr => self.repr[],
             None => ".",
-            Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => {
-                self.repr.as_slice()
-            }
-            Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => {
-                self.repr.as_slice()
-            }
-            Some((0,idxa,_)) => self.repr.slice_to(idxa),
+            Some((_,idxa,end)) if self.repr[idxa..end] == ".." => self.repr[],
+            Some((idxb,_,end)) if self.repr[idxb..end] == "\\" => self.repr[],
+            Some((0,idxa,_)) => self.repr[0..idxa],
             Some((idxb,idxa,_)) => {
                 match self.prefix {
                     Some(DiskPrefix) | Some(VerbatimDiskPrefix) if idxb == self.prefix_len() => {
-                        self.repr.slice_to(idxa)
+                        self.repr[0..idxa]
                     }
-                    _ => self.repr.slice_to(idxb)
+                    _ => self.repr[0..idxb]
                 }
             }
         })
@@ -384,13 +380,13 @@ impl GenericPath for Path {
     /// See `GenericPath::filename_str` for info.
     /// Always returns a `Some` value if `filename` returns a `Some` value.
     fn filename_str<'a>(&'a self) -> Option<&'a str> {
-        let repr = self.repr.as_slice();
+        let repr = self.repr[];
         match self.sepidx_or_prefix_len() {
             None if "." == repr || ".." == repr => None,
             None => Some(repr),
-            Some((_,idxa,end)) if repr.slice(idxa, end) == ".." => None,
+            Some((_,idxa,end)) if repr[idxa..end] == ".." => None,
             Some((_,idxa,end)) if idxa == end => None,
-            Some((_,idxa,end)) => Some(repr.slice(idxa, end))
+            Some((_,idxa,end)) => Some(repr[idxa..end])
         }
     }
 
@@ -422,7 +418,7 @@ impl GenericPath for Path {
                 true
             }
             Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false,
-            Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => false,
+            Some((idxb,_,end)) if self.repr[idxb..end] == "\\" => false,
             Some((idxb,idxa,_)) => {
                 let trunc = match self.prefix {
                     Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => {
@@ -442,15 +438,15 @@ impl GenericPath for Path {
         if self.prefix.is_some() {
             Some(Path::new(match self.prefix {
                 Some(DiskPrefix) if self.is_absolute() => {
-                    self.repr.slice_to(self.prefix_len()+1)
+                    self.repr[0..self.prefix_len()+1]
                 }
                 Some(VerbatimDiskPrefix) => {
-                    self.repr.slice_to(self.prefix_len()+1)
+                    self.repr[0..self.prefix_len()+1]
                 }
-                _ => self.repr.slice_to(self.prefix_len())
+                _ => self.repr[0..self.prefix_len()]
             }))
         } else if is_vol_relative(self) {
-            Some(Path::new(self.repr.slice_to(1)))
+            Some(Path::new(self.repr[0..1]))
         } else {
             None
         }
@@ -469,7 +465,7 @@ impl GenericPath for Path {
     fn is_absolute(&self) -> bool {
         match self.prefix {
             Some(DiskPrefix) => {
-                let rest = self.repr.slice_from(self.prefix_len());
+                let rest = self.repr[self.prefix_len()..];
                 rest.len() > 0 && rest.as_bytes()[0] == SEP_BYTE
             }
             Some(_) => true,
@@ -644,18 +640,19 @@ impl Path {
     /// Does not distinguish between absolute and cwd-relative paths, e.g.
     /// C:\foo and C:foo.
     pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
-        let repr = self.repr.as_slice();
+        let repr = self.repr[];
         let s = match self.prefix {
             Some(_) => {
                 let plen = self.prefix_len();
                 if repr.len() > plen && repr.as_bytes()[plen] == SEP_BYTE {
-                    repr.slice_from(plen+1)
-                } else { repr.slice_from(plen) }
+                    repr[plen+1..]
+                } else { repr[plen..] }
             }
-            None if repr.as_bytes()[0] == SEP_BYTE => repr.slice_from(1),
+            None if repr.as_bytes()[0] == SEP_BYTE => repr[1..],
             None => repr
         };
-        let ret = s.split_terminator(SEP).map(Some);
+        let some: fn(&'a str) -> Option<&'a str> = Some; // coerce to fn ptr
+        let ret = s.split_terminator(SEP).map(some);
         ret
     }
 
@@ -666,12 +663,13 @@ impl Path {
             #![inline]
             x.unwrap().as_bytes()
         }
+        let convert: for<'b> fn(Option<&'b str>) -> &'b [u8] = convert; // coerce to fn ptr
         self.str_components().map(convert)
     }
 
     fn equiv_prefix(&self, other: &Path) -> bool {
-        let s_repr = self.repr.as_slice();
-        let o_repr = other.repr.as_slice();
+        let s_repr = self.repr[];
+        let o_repr = other.repr[];
         match (self.prefix, other.prefix) {
             (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => {
                 self.is_absolute() &&
@@ -688,28 +686,28 @@ impl Path {
                     o_repr.as_bytes()[4].to_ascii().to_lowercase()
             }
             (Some(UNCPrefix(_,_)), Some(VerbatimUNCPrefix(_,_))) => {
-                s_repr.slice(2, self.prefix_len()) == o_repr.slice(8, other.prefix_len())
+                s_repr[2..self.prefix_len()] == o_repr[8..other.prefix_len()]
             }
             (Some(VerbatimUNCPrefix(_,_)), Some(UNCPrefix(_,_))) => {
-                s_repr.slice(8, self.prefix_len()) == o_repr.slice(2, other.prefix_len())
+                s_repr[8..self.prefix_len()] == o_repr[2..other.prefix_len()]
             }
             (None, None) => true,
             (a, b) if a == b => {
-                s_repr.slice_to(self.prefix_len()) == o_repr.slice_to(other.prefix_len())
+                s_repr[0..self.prefix_len()] == o_repr[0..other.prefix_len()]
             }
             _ => false
         }
     }
 
-    fn normalize_<S: StrAllocating>(s: S) -> (Option<PathPrefix>, String) {
+    fn normalize_(s: &str) -> (Option<PathPrefix>, String) {
         // make borrowck happy
         let (prefix, val) = {
-            let prefix = parse_prefix(s.as_slice());
-            let path = Path::normalize__(s.as_slice(), prefix);
+            let prefix = parse_prefix(s);
+            let path = Path::normalize__(s, prefix);
             (prefix, path)
         };
         (prefix, match val {
-            None => s.into_string(),
+            None => s.to_string(),
             Some(val) => val
         })
     }
@@ -749,7 +747,7 @@ impl Path {
                         match prefix.unwrap() {
                             DiskPrefix => {
                                 let len = prefix_len(prefix) + is_abs as uint;
-                                let mut s = String::from_str(s.slice_to(len));
+                                let mut s = String::from_str(s[0..len]);
                                 unsafe {
                                     let v = s.as_mut_vec();
                                     v[0] = (*v)[0].to_ascii().to_uppercase().as_byte();
@@ -764,7 +762,7 @@ impl Path {
                             }
                             VerbatimDiskPrefix => {
                                 let len = prefix_len(prefix) + is_abs as uint;
-                                let mut s = String::from_str(s.slice_to(len));
+                                let mut s = String::from_str(s[0..len]);
                                 unsafe {
                                     let v = s.as_mut_vec();
                                     v[4] = (*v)[4].to_ascii().to_uppercase().as_byte();
@@ -774,14 +772,14 @@ impl Path {
                             _ => {
                                 let plen = prefix_len(prefix);
                                 if s.len() > plen {
-                                    Some(String::from_str(s.slice_to(plen)))
+                                    Some(String::from_str(s[0..plen]))
                                 } else { None }
                             }
                         }
                     } else if is_abs && comps.is_empty() {
                         Some(String::from_char(1, SEP))
                     } else {
-                        let prefix_ = s.slice_to(prefix_len(prefix));
+                        let prefix_ = s[0..prefix_len(prefix)];
                         let n = prefix_.len() +
                                 if is_abs { comps.len() } else { comps.len() - 1} +
                                 comps.iter().map(|v| v.len()).sum();
@@ -793,16 +791,16 @@ impl Path {
                                 s.push(':');
                             }
                             Some(VerbatimDiskPrefix) => {
-                                s.push_str(prefix_.slice_to(4));
+                                s.push_str(prefix_[0..4]);
                                 s.push(prefix_.as_bytes()[4].to_ascii()
                                                    .to_uppercase().as_char());
-                                s.push_str(prefix_.slice_from(5));
+                                s.push_str(prefix_[5..]);
                             }
                             Some(UNCPrefix(a,b)) => {
                                 s.push_str("\\\\");
-                                s.push_str(prefix_.slice(2, a+2));
+                                s.push_str(prefix_[2..a+2]);
                                 s.push(SEP);
-                                s.push_str(prefix_.slice(3+a, 3+a+b));
+                                s.push_str(prefix_[3+a..3+a+b]);
                             }
                             Some(_) => s.push_str(prefix_),
                             None => ()
@@ -827,10 +825,14 @@ impl Path {
 
     fn update_sepidx(&mut self) {
         let s = if self.has_nonsemantic_trailing_slash() {
-                    self.repr.slice_to(self.repr.len()-1)
-                } else { self.repr.as_slice() };
-        let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep }
-                          else { is_sep_verbatim });
+                    self.repr[0..self.repr.len()-1]
+                } else { self.repr[] };
+        let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) {
+            is_sep
+        } else {
+            is_sep_verbatim
+        };
+        let idx = s.rfind(sep_test);
         let prefixlen = self.prefix_len();
         self.sepidx = idx.and_then(|x| if x < prefixlen { None } else { Some(x) });
     }
@@ -860,8 +862,8 @@ impl Path {
             self.repr.as_bytes()[self.repr.len()-1] == SEP_BYTE
     }
 
-    fn update_normalized<S: Str>(&mut self, s: S) {
-        let (prefix, path) = Path::normalize_(s.as_slice());
+    fn update_normalized(&mut self, s: &str) {
+        let (prefix, path) = Path::normalize_(s);
         self.repr = path;
         self.prefix = prefix;
         self.update_sepidx();
@@ -903,17 +905,17 @@ pub fn is_verbatim(path: &Path) -> bool {
 /// non-verbatim, the non-verbatim version is returned.
 /// Otherwise, None is returned.
 pub fn make_non_verbatim(path: &Path) -> Option<Path> {
-    let repr = path.repr.as_slice();
+    let repr = path.repr[];
     let new_path = match path.prefix {
         Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None,
         Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()),
         Some(VerbatimDiskPrefix) => {
             // \\?\D:\
-            Path::new(repr.slice_from(4))
+            Path::new(repr[4..])
         }
         Some(VerbatimUNCPrefix(_,_)) => {
             // \\?\UNC\server\share
-            Path::new(format!(r"\{}", repr.slice_from(7)))
+            Path::new(format!(r"\{}", repr[7..]))
         }
     };
     if new_path.prefix.is_none() {
@@ -922,8 +924,8 @@ pub fn make_non_verbatim(path: &Path) -> Option<Path> {
         return None;
     }
     // now ensure normalization didn't change anything
-    if repr.slice_from(path.prefix_len()) ==
-        new_path.repr.slice_from(new_path.prefix_len()) {
+    if repr[path.prefix_len()..] ==
+        new_path.repr[new_path.prefix_len()..] {
         Some(new_path)
     } else {
         None
@@ -988,13 +990,13 @@ pub enum PathPrefix {
 fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
     if path.starts_with("\\\\") {
         // \\
-        path = path.slice_from(2);
+        path = path[2..];
         if path.starts_with("?\\") {
             // \\?\
-            path = path.slice_from(2);
+            path = path[2..];
             if path.starts_with("UNC\\") {
                 // \\?\UNC\server\share
-                path = path.slice_from(4);
+                path = path[4..];
                 let (idx_a, idx_b) = match parse_two_comps(path, is_sep_verbatim) {
                     Some(x) => x,
                     None => (path.len(), 0)
@@ -1015,7 +1017,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
             }
         } else if path.starts_with(".\\") {
             // \\.\path
-            path = path.slice_from(2);
+            path = path[2..];
             let idx = path.find('\\').unwrap_or(path.len());
             return Some(DeviceNSPrefix(idx));
         }
@@ -1040,7 +1042,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
             None => return None,
             Some(x) => x
         };
-        path = path.slice_from(idx_a+1);
+        path = path[idx_a+1..];
         let idx_b = path.find(f).unwrap_or(path.len());
         Some((idx_a, idx_b))
     }
@@ -1048,10 +1050,14 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
 
 // None result means the string didn't need normalizing
 fn normalize_helper<'a>(s: &'a str, prefix: Option<PathPrefix>) -> (bool, Option<Vec<&'a str>>) {
-    let f = if !prefix_is_verbatim(prefix) { is_sep } else { is_sep_verbatim };
+    let f: fn(char) -> bool = if !prefix_is_verbatim(prefix) {
+        is_sep
+    } else {
+        is_sep_verbatim
+    };
     let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix)));
-    let s_ = s.slice_from(prefix_len(prefix));
-    let s_ = if is_abs { s_.slice_from(1) } else { s_ };
+    let s_ = s[prefix_len(prefix)..];
+    let s_ = if is_abs { s_[1..] } else { s_ };
 
     if is_abs && s_.is_empty() {
         return (is_abs, match prefix {
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index f77627711a7..49b888d17f4 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -79,11 +79,11 @@
 #[doc(no_inline)] pub use result::Result;
 #[doc(no_inline)] pub use result::Result::{Ok, Err};
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
-#[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude};
-#[doc(no_inline)] pub use str::{StrAllocating, UnicodeStrPrelude};
 #[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4};
 #[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8};
 #[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
+#[doc(no_inline)] pub use str::{Str, StrVector};
+#[doc(no_inline)] pub use str::StrExt;
 #[doc(no_inline)] pub use slice::AsSlice;
 #[doc(no_inline)] pub use slice::{VectorVector, PartialEqSliceExt};
 #[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 4a692bccf9e..775e9bb526f 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -12,7 +12,8 @@
 
 #![allow(non_camel_case_types)]
 
-use option::Option::{Some, None};
+use prelude::*;
+
 use os;
 use sync::atomic;
 
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 8d9c1268e7e..d64336569c6 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -91,7 +91,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
         // created. Note that this isn't necessary in general for new threads,
         // but we just do this to name the main thread and to give it correct
         // info about the stack bounds.
-        let thread: Thread = NewThread::new(Some("<main>".into_string()));
+        let thread: Thread = NewThread::new(Some("<main>".to_string()));
         thread_info::set((my_stack_bottom, my_stack_top),
                          sys::thread::guard::main(),
                          thread);
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index f572141642c..eb15a7ba378 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -512,7 +512,7 @@ pub fn begin_unwind_fmt(msg: &fmt::Arguments, file_line: &(&'static str, uint))
     let mut v = Vec::new();
     let _ = write!(&mut VecWriter { v: &mut v }, "{}", msg);
 
-    let msg = box String::from_utf8_lossy(v.as_slice()).into_string();
+    let msg = box String::from_utf8_lossy(v.as_slice()).into_owned();
     begin_unwind_inner(msg, file_line)
 }
 
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 77500ca74d0..d8cd8455deb 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -10,16 +10,16 @@
 //
 // ignore-lexer-test FIXME #15677
 
-use core::prelude::*;
+use prelude::*;
 
-use core::cmp;
-use core::fmt;
-use core::intrinsics;
-use core::slice;
-use core::str;
-
-use libc::{mod, uintptr_t};
+use cmp;
+use fmt;
+use intrinsics;
+use libc::uintptr_t;
+use libc;
 use os;
+use slice;
+use str;
 use sync::atomic;
 
 /// Dynamically inquire about whether we're running under V.
@@ -52,7 +52,7 @@ pub fn min_stack() -> uint {
         0 => {}
         n => return n - 1,
     }
-    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| from_str(s.as_slice()));
+    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse());
     let amt = amt.unwrap_or(2 * 1024 * 1024);
     // 0 is our sentinel value, so ensure that we'll never see 0 after
     // initialization has run
@@ -65,7 +65,7 @@ pub fn min_stack() -> uint {
 pub fn default_sched_threads() -> uint {
     match os::getenv("RUST_THREADS") {
         Some(nstr) => {
-            let opt_n: Option<uint> = from_str(nstr.as_slice());
+            let opt_n: Option<uint> = nstr.parse();
             match opt_n {
                 Some(n) if n > 0 => n,
                 _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
@@ -113,9 +113,8 @@ impl fmt::FormatWriter for Stdio {
 }
 
 pub fn dumb_print(args: &fmt::Arguments) {
-    use fmt::FormatWriter;
     let mut w = Stderr;
-    let _ = w.write_fmt(args);
+    let _ = write!(&mut w, "{}", args);
 }
 
 pub fn abort(args: &fmt::Arguments) -> ! {
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index a39c8d6d8fe..1d646eb06b1 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -8,12 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use io::{IoResult, Writer};
-use iter::{Iterator, IteratorExt};
-use option::Option::{Some, None};
-use result::Result::{Ok, Err};
-use str::{StrPrelude, from_str};
-use unicode::char::UnicodeChar;
+use prelude::*;
+
+use io::IoResult;
 
 #[cfg(target_word_size = "64")] pub const HEX_WIDTH: uint = 18;
 #[cfg(target_word_size = "32")] pub const HEX_WIDTH: uint = 10;
@@ -85,7 +82,7 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
             while rest.char_at(0).is_numeric() {
                 rest = rest.slice_from(1);
             }
-            let i: uint = from_str(inner.slice_to(inner.len() - rest.len())).unwrap();
+            let i: uint = inner.slice_to(inner.len() - rest.len()).parse().unwrap();
             inner = rest.slice_from(i);
             rest = rest.slice_to(i);
             while rest.len() > 0 {
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 6c909d7562d..316d97064ee 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -189,7 +189,7 @@ pub fn load_self() -> Option<Vec<u8>> {
         if sz == 0 { return None; }
         let mut v: Vec<u8> = Vec::with_capacity(sz as uint);
         let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
-                         v.as_mut_ptr() as *mut c_void, &mut sz,
+                         v.as_mut_ptr() as *mut libc::c_void, &mut sz,
                          ptr::null_mut(), 0u as libc::size_t);
         if err != 0 { return None; }
         if sz == 0 { return None; }
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index f2f543dd969..42c8f7705e1 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -32,7 +32,7 @@ use path::Path;
 use result::Result::{Ok, Err};
 use sync::{StaticMutex, MUTEX_INIT};
 use slice::SliceExt;
-use str::StrPrelude;
+use str::StrExt;
 use dynamic_lib::DynamicLibrary;
 
 use sys_common::backtrace::*;
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index d5bf8c5b629..15eddd569be 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -23,6 +23,7 @@ use io;
 
 use prelude::*;
 use sys;
+use sys::os;
 use sys_common::{keep_going, eof, mkerr_libc};
 
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
@@ -262,7 +263,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
             let mut more_files = 1 as libc::BOOL;
             while more_files != 0 {
                 {
-                    let filename = str::truncate_utf16_at_nul(&wfd.cFileName);
+                    let filename = os::truncate_utf16_at_nul(&wfd.cFileName);
                     match String::from_utf16(filename) {
                         Some(filename) => paths.push(Path::new(filename)),
                         None => {
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index e2220b7b67b..e007b46b261 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -31,6 +31,16 @@ use libc::types::os::arch::extra::DWORD;
 
 const BUF_BYTES : uint = 2048u;
 
+/// Return a slice of `v` ending at (and not including) the first NUL
+/// (0).
+pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
+    match v.iter().position(|c| *c == 0) {
+        // don't include the 0
+        Some(i) => v[..i],
+        None => v
+    }
+}
+
 pub fn errno() -> uint {
     use libc::types::os::arch::extra::DWORD;
 
@@ -87,7 +97,7 @@ pub fn error_string(errnum: i32) -> String {
             return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err);
         }
 
-        let msg = String::from_utf16(::str::truncate_utf16_at_nul(&buf));
+        let msg = String::from_utf16(truncate_utf16_at_nul(&buf));
         match msg {
             Some(msg) => format!("OS Error {}: {}", errnum, msg),
             None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum),
@@ -158,7 +168,7 @@ pub fn getcwd() -> IoResult<Path> {
         }
     }
 
-    match String::from_utf16(::str::truncate_utf16_at_nul(&buf)) {
+    match String::from_utf16(truncate_utf16_at_nul(&buf)) {
         Some(ref cwd) => Ok(Path::new(cwd)),
         None => Err(IoError {
             kind: OtherIoError,
@@ -269,7 +279,7 @@ pub fn load_self() -> Option<Vec<u8>> {
     unsafe {
         fill_utf16_buf_and_decode(|buf, sz| {
             libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
-        }).map(|s| s.into_string().into_bytes())
+        }).map(|s| s.to_string().into_bytes())
     }
 }
 
@@ -294,3 +304,30 @@ pub fn page_size() -> uint {
         return info.dwPageSize as uint;
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::truncate_utf16_at_nul;
+
+    #[test]
+    fn test_truncate_utf16_at_nul() {
+        let v = [];
+        let b: &[u16] = &[];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [0, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 0, 3];
+        let b: &[u16] = &[1];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 2, 0];
+        let b: &[u16] = &[1, 2];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 2, 3];
+        let b: &[u16] = &[1, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+    }
+}
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 8945c155e66..0c2c76077dd 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -122,7 +122,7 @@ impl Process {
 
         use mem;
         use iter::{Iterator, IteratorExt};
-        use str::StrPrelude;
+        use str::StrExt;
 
         if cfg.gid().is_some() || cfg.uid().is_some() {
             return Err(IoError {
diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs
index 51679bb2003..f793de5bb57 100644
--- a/src/libstd/sys/windows/tty.rs
+++ b/src/libstd/sys/windows/tty.rs
@@ -111,7 +111,7 @@ impl TTY {
     }
 
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        let utf16 = match from_utf8(buf) {
+        let utf16 = match from_utf8(buf).ok() {
             Some(utf8) => {
                 utf8.utf16_units().collect::<Vec<u16>>()
             }
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 4c33d1c418d..04718dcc6ae 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -189,11 +189,12 @@ macro_rules! __thread_local_inner {
             }
         };
 
-        #[cfg(not(any(target_os = "macos", target_os = "linux")))]
+        #[cfg(all(stage0, not(any(target_os = "macos", target_os = "linux"))))]
         const INIT: ::std::thread_local::KeyInner<$t> = {
             unsafe extern fn __destroy(ptr: *mut u8) {
                 ::std::thread_local::destroy_value::<$t>(ptr);
             }
+
             ::std::thread_local::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: $init },
                 os: ::std::thread_local::OsStaticKey {
@@ -203,6 +204,21 @@ macro_rules! __thread_local_inner {
             }
         };
 
+        #[cfg(all(not(stage0), not(any(target_os = "macos", target_os = "linux"))))]
+        const INIT: ::std::thread_local::KeyInner<$t> = {
+            unsafe extern fn __destroy(ptr: *mut u8) {
+                ::std::thread_local::destroy_value::<$t>(ptr);
+            }
+
+            ::std::thread_local::KeyInner {
+                inner: ::std::cell::UnsafeCell { value: $init },
+                os: ::std::thread_local::OsStaticKey {
+                    inner: ::std::thread_local::OS_INIT_INNER,
+                    dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)),
+                },
+            }
+        };
+
         INIT
     });
 }
@@ -323,6 +339,12 @@ mod imp {
         // *should* be the case that this loop always terminates because we
         // provide the guarantee that a TLS key cannot be set after it is
         // flagged for destruction.
+        #[cfg(not(stage0))]
+        static DTORS: os::StaticKey = os::StaticKey {
+            inner: os::INIT_INNER,
+            dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)),
+        };
+        #[cfg(stage0)]
         static DTORS: os::StaticKey = os::StaticKey {
             inner: os::INIT_INNER,
             dtor: Some(run_dtors),