about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-06 16:21:02 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-06 16:21:02 -0700
commit5eaa4d1d2f6eafc4233892d3d1dafb0d05799ac3 (patch)
tree3ee757ce4806cf7686f0508952149f2a75d0d0f3 /src/libstd
parent5e7b6662502a82b6f1a789277d3dc2e68aa4eb13 (diff)
parent6972eb4cd7702a343a7e79c4a57522d0de763327 (diff)
downloadrust-5eaa4d1d2f6eafc4233892d3d1dafb0d05799ac3.tar.gz
rust-5eaa4d1d2f6eafc4233892d3d1dafb0d05799ac3.zip
Merge remote-tracking branch 'remotes/origin/master' into remove-str-trailing-nulls
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs6
-rw-r--r--src/libstd/either.rs366
-rw-r--r--src/libstd/hashmap.rs54
-rw-r--r--src/libstd/io.rs2
-rw-r--r--src/libstd/iterator.rs65
-rw-r--r--src/libstd/local_data.rs14
-rw-r--r--src/libstd/num/strconv.rs2
-rw-r--r--src/libstd/num/uint.rs24
-rw-r--r--src/libstd/option.rs258
-rw-r--r--src/libstd/os.rs6
-rw-r--r--src/libstd/ptr.rs7
-rw-r--r--src/libstd/rand.rs4
-rw-r--r--src/libstd/result.rs357
-rw-r--r--src/libstd/rt/io/flate.rs4
-rw-r--r--src/libstd/rt/io/mod.rs36
-rw-r--r--src/libstd/rt/kill.rs13
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/task.rs4
-rw-r--r--src/libstd/rt/test.rs4
-rw-r--r--src/libstd/rt/util.rs4
-rw-r--r--src/libstd/rt/uv/net.rs6
-rw-r--r--src/libstd/rt/uv/uvio.rs2
-rw-r--r--src/libstd/str.rs6
-rw-r--r--src/libstd/task/mod.rs2
-rw-r--r--src/libstd/task/spawn.rs104
-rw-r--r--src/libstd/trie.rs94
-rw-r--r--src/libstd/vec.rs68
27 files changed, 831 insertions, 683 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 4ece53d0e7f..a84f3137bbd 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -78,10 +78,8 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> @[A] {
  *             onto the vector being constructed.
  */
 #[inline]
-pub fn build_sized_opt<A>(size: Option<uint>,
-                          builder: &fn(push: &fn(v: A)))
-                       -> @[A] {
-    build_sized(size.get_or_default(4), builder)
+pub fn build_sized_opt<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
+    build_sized(size.unwrap_or_default(4), builder)
 }
 
 // Appending
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index 6bdc45d7204..cfaef550c6f 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -23,29 +23,102 @@ use str::StrSlice;
 use vec;
 use vec::{OwnedVector, ImmutableVector};
 
-/// The either type
+/// `Either` is a type that represents one of two alternatives
 #[deriving(Clone, Eq)]
-pub enum Either<T, U> {
-    Left(T),
-    Right(U)
+pub enum Either<L, R> {
+    Left(L),
+    Right(R)
 }
 
-/// Applies a function based on the given either value
-///
-/// If `value` is left(T) then `f_left` is applied to its contents, if
-/// `value` is right(U) then `f_right` is applied to its contents, and the
-/// result is returned.
-#[inline]
-pub fn either<T, U, V>(f_left: &fn(&T) -> V,
-                       f_right: &fn(&U) -> V, value: &Either<T, U>) -> V {
-    match *value {
-        Left(ref l) => f_left(l),
-        Right(ref r) => f_right(r)
+impl<L, R> Either<L, R> {
+    /// Applies a function based on the given either value
+    ///
+    /// If `value` is `Left(L)` then `f_left` is applied to its contents, if
+    /// `value` is `Right(R)` then `f_right` is applied to its contents, and the
+    /// result is returned.
+    #[inline]
+    pub fn either<T>(&self, f_left: &fn(&L) -> T, f_right: &fn(&R) -> T) -> T {
+        match *self {
+            Left(ref l) => f_left(l),
+            Right(ref r) => f_right(r)
+        }
+    }
+
+    /// Flips between left and right of a given `Either`
+    #[inline]
+    pub fn flip(self) -> Either<R, L> {
+        match self {
+            Right(r) => Left(r),
+            Left(l) => Right(l)
+        }
+    }
+
+    /// Converts a `Either` to a `Result`
+    ///
+    /// Converts an `Either` type to a `Result` type, making the "right" choice
+    /// an `Ok` result, and the "left" choice a `Err`
+    #[inline]
+    pub fn to_result(self) -> Result<R, L> {
+        match self {
+            Right(r) => result::Ok(r),
+            Left(l) => result::Err(l)
+        }
+    }
+
+    /// Checks whether the given value is a `Left`
+    #[inline]
+    pub fn is_left(&self) -> bool {
+        match *self {
+            Left(_) => true,
+            _ => false
+        }
+    }
+
+    /// Checks whether the given value is a `Right`
+    #[inline]
+    pub fn is_right(&self) -> bool {
+        match *self {
+            Right(_) => true,
+            _ => false
+        }
+    }
+
+    /// Retrieves the value from a `Left`.
+    /// Fails with a specified reason if the `Either` is `Right`.
+    #[inline]
+    pub fn expect_left(self, reason: &str) -> L {
+        match self {
+            Left(x) => x,
+            Right(_) => fail!(reason.to_owned())
+        }
+    }
+
+    /// Retrieves the value from a `Left`. Fails if the `Either` is `Right`.
+    #[inline]
+    pub fn unwrap_left(self) -> L {
+        self.expect_left("called Either::unwrap_left()` on `Right` value")
+    }
+
+    /// Retrieves the value from a `Right`.
+    /// Fails with a specified reason if the `Either` is `Left`.
+    #[inline]
+    pub fn expect_right(self, reason: &str) -> R {
+        match self {
+            Right(x) => x,
+            Left(_) => fail!(reason.to_owned())
+        }
+    }
+
+    /// Retrieves the value from a `Right`. Fails if the `Either` is `Left`.
+    #[inline]
+    pub fn unwrap_right(self) -> R {
+        self.expect_right("called Either::unwrap_right()` on `Left` value")
     }
 }
 
+// FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the left values
-pub fn lefts<T:Clone,U>(eithers: &[Either<T, U>]) -> ~[T] {
+pub fn lefts<L: Clone, R>(eithers: &[Either<L, R>]) -> ~[L] {
     do vec::build_sized(eithers.len()) |push| {
         for elt in eithers.iter() {
             match *elt {
@@ -56,8 +129,9 @@ pub fn lefts<T:Clone,U>(eithers: &[Either<T, U>]) -> ~[T] {
     }
 }
 
+// FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the right values
-pub fn rights<T, U: Clone>(eithers: &[Either<T, U>]) -> ~[U] {
+pub fn rights<L, R: Clone>(eithers: &[Either<L, R>]) -> ~[R] {
     do vec::build_sized(eithers.len()) |push| {
         for elt in eithers.iter() {
             match *elt {
@@ -68,13 +142,14 @@ pub fn rights<T, U: Clone>(eithers: &[Either<T, U>]) -> ~[U] {
     }
 }
 
+// FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the left values and right values
 ///
 /// Returns a structure containing a vector of left values and a vector of
 /// right values.
-pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
-    let mut lefts: ~[T] = ~[];
-    let mut rights: ~[U] = ~[];
+pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
+    let mut lefts: ~[L] = ~[];
+    let mut rights: ~[R] = ~[];
     for elt in eithers.consume_iter() {
         match elt {
             Left(l) => lefts.push(l),
@@ -84,196 +159,101 @@ pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
     return (lefts, rights);
 }
 
-/// Flips between left and right of a given either
-#[inline]
-pub fn flip<T, U>(eith: Either<T, U>) -> Either<U, T> {
-    match eith {
-        Right(r) => Left(r),
-        Left(l) => Right(l)
-    }
-}
+#[cfg(test)]
+mod tests {
+    use super::*;
 
-/// Converts either::t to a result::t
-///
-/// Converts an `either` type to a `result` type, making the "right" choice
-/// an ok result, and the "left" choice a fail
-#[inline]
-pub fn to_result<T, U>(eith: Either<T, U>) -> Result<U, T> {
-    match eith {
-        Right(r) => result::Ok(r),
-        Left(l) => result::Err(l)
+    #[test]
+    fn test_either_left() {
+        let val = Left(10);
+        fn f_left(x: &int) -> bool { *x == 10 }
+        fn f_right(_x: &uint) -> bool { false }
+        assert!(val.either(f_left, f_right));
     }
-}
 
-/// Checks whether the given value is a left
-#[inline]
-pub fn is_left<T, U>(eith: &Either<T, U>) -> bool {
-    match *eith {
-        Left(_) => true,
-        _ => false
+    #[test]
+    fn test_either_right() {
+        let val = Right(10u);
+        fn f_left(_x: &int) -> bool { false }
+        fn f_right(x: &uint) -> bool { *x == 10u }
+        assert!(val.either(f_left, f_right));
     }
-}
 
-/// Checks whether the given value is a right
-#[inline]
-pub fn is_right<T, U>(eith: &Either<T, U>) -> bool {
-    match *eith {
-        Right(_) => true,
-        _ => false
+    #[test]
+    fn test_lefts() {
+        let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
+        let result = lefts(input);
+        assert_eq!(result, ~[10, 12, 14]);
     }
-}
 
-/// Retrieves the value in the left branch.
-/// Fails with a specified reason if the either is Right.
-#[inline]
-pub fn expect_left<T,U>(eith: Either<T,U>, reason: &str) -> T {
-    match eith {
-        Left(x) => x,
-        Right(_) => fail!(reason.to_owned())
+    #[test]
+    fn test_lefts_none() {
+        let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
+        let result = lefts(input);
+        assert_eq!(result.len(), 0u);
     }
-}
 
-/// Retrieves the value in the left branch. Fails if the either is Right.
-#[inline]
-pub fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
-    expect_left(eith, "either::unwrap_left Right")
-}
-
-/// Retrieves the value in the right branch.
-/// Fails with a specified reason if the either is Left.
-#[inline]
-pub fn expect_right<T,U>(eith: Either<T,U>, reason: &str) -> U {
-    match eith {
-        Right(x) => x,
-        Left(_) => fail!(reason.to_owned())
+    #[test]
+    fn test_lefts_empty() {
+        let input: ~[Either<int, int>] = ~[];
+        let result = lefts(input);
+        assert_eq!(result.len(), 0u);
     }
-}
 
-/// Retrieves the value in the right branch. Fails if the either is Left.
-pub fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
-    expect_right(eith, "either::unwrap_right Left")
-}
-
-impl<T, U> Either<T, U> {
-    #[inline]
-    pub fn either<V>(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V {
-        either(f_left, f_right, self)
+    #[test]
+    fn test_rights() {
+        let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
+        let result = rights(input);
+        assert_eq!(result, ~[11, 13]);
     }
 
-    #[inline]
-    pub fn flip(self) -> Either<U, T> { flip(self) }
-
-    #[inline]
-    pub fn to_result(self) -> Result<U, T> { to_result(self) }
-
-    #[inline]
-    pub fn is_left(&self) -> bool { is_left(self) }
-
-    #[inline]
-    pub fn is_right(&self) -> bool { is_right(self) }
-
-    #[inline]
-    pub fn expect_left(self, reason: &str) -> T { expect_left(self, reason) }
-
-    #[inline]
-    pub fn unwrap_left(self) -> T { unwrap_left(self) }
-
-    #[inline]
-    pub fn expect_right(self, reason: &str) -> U { expect_right(self, reason) }
-
-    #[inline]
-    pub fn unwrap_right(self) -> U { unwrap_right(self) }
-}
-
-#[test]
-fn test_either_left() {
-    let val = Left(10);
-    fn f_left(x: &int) -> bool { *x == 10 }
-    fn f_right(_x: &uint) -> bool { false }
-    assert!((either(f_left, f_right, &val)));
-}
-
-#[test]
-fn test_either_right() {
-    let val = Right(10u);
-    fn f_left(_x: &int) -> bool { false }
-    fn f_right(x: &uint) -> bool { *x == 10u }
-    assert!((either(f_left, f_right, &val)));
-}
-
-#[test]
-fn test_lefts() {
-    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-    let result = lefts(input);
-    assert_eq!(result, ~[10, 12, 14]);
-}
-
-#[test]
-fn test_lefts_none() {
-    let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
-    let result = lefts(input);
-    assert_eq!(result.len(), 0u);
-}
-
-#[test]
-fn test_lefts_empty() {
-    let input: ~[Either<int, int>] = ~[];
-    let result = lefts(input);
-    assert_eq!(result.len(), 0u);
-}
-
-#[test]
-fn test_rights() {
-    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-    let result = rights(input);
-    assert_eq!(result, ~[11, 13]);
-}
+    #[test]
+    fn test_rights_none() {
+        let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
+        let result = rights(input);
+        assert_eq!(result.len(), 0u);
+    }
 
-#[test]
-fn test_rights_none() {
-    let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
-    let result = rights(input);
-    assert_eq!(result.len(), 0u);
-}
+    #[test]
+    fn test_rights_empty() {
+        let input: ~[Either<int, int>] = ~[];
+        let result = rights(input);
+        assert_eq!(result.len(), 0u);
+    }
 
-#[test]
-fn test_rights_empty() {
-    let input: ~[Either<int, int>] = ~[];
-    let result = rights(input);
-    assert_eq!(result.len(), 0u);
-}
+    #[test]
+    fn test_partition() {
+        let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
+        let (lefts, rights) = partition(input);
+        assert_eq!(lefts[0], 10);
+        assert_eq!(lefts[1], 12);
+        assert_eq!(lefts[2], 14);
+        assert_eq!(rights[0], 11);
+        assert_eq!(rights[1], 13);
+    }
 
-#[test]
-fn test_partition() {
-    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-    let (lefts, rights) = partition(input);
-    assert_eq!(lefts[0], 10);
-    assert_eq!(lefts[1], 12);
-    assert_eq!(lefts[2], 14);
-    assert_eq!(rights[0], 11);
-    assert_eq!(rights[1], 13);
-}
+    #[test]
+    fn test_partition_no_lefts() {
+        let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
+        let (lefts, rights) = partition(input);
+        assert_eq!(lefts.len(), 0u);
+        assert_eq!(rights.len(), 2u);
+    }
 
-#[test]
-fn test_partition_no_lefts() {
-    let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
-    let (lefts, rights) = partition(input);
-    assert_eq!(lefts.len(), 0u);
-    assert_eq!(rights.len(), 2u);
-}
+    #[test]
+    fn test_partition_no_rights() {
+        let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
+        let (lefts, rights) = partition(input);
+        assert_eq!(lefts.len(), 2u);
+        assert_eq!(rights.len(), 0u);
+    }
 
-#[test]
-fn test_partition_no_rights() {
-    let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
-    let (lefts, rights) = partition(input);
-    assert_eq!(lefts.len(), 2u);
-    assert_eq!(rights.len(), 0u);
-}
+    #[test]
+    fn test_partition_empty() {
+        let input: ~[Either<int, int>] = ~[];
+        let (lefts, rights) = partition(input);
+        assert_eq!(lefts.len(), 0u);
+        assert_eq!(rights.len(), 0u);
+    }
 
-#[test]
-fn test_partition_empty() {
-    let input: ~[Either<int, int>] = ~[];
-    let (lefts, rights) = partition(input);
-    assert_eq!(lefts.len(), 0u);
-    assert_eq!(rights.len(), 0u);
 }
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 658f854c50d..fbc471c0ae0 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
 use clone::Clone;
 use cmp::{Eq, Equiv};
 use hash::Hash;
-use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain, range};
+use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range};
+use iterator::{FilterMap, Chain, Repeat, Zip};
 use num;
 use option::{None, Option, Some};
 use rand::RngUtil;
@@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> {
     }
 
     /// Visit the values representing the difference
-    pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>)
-        -> SetAlgebraIter<'a, T> {
-        EnvFilterIterator{iter: self.iter(), env: other,
-                          filter: |elt, other| !other.contains(elt) }
+    pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> {
+        Repeat::new(other)
+            .zip(self.iter())
+            .filter_map(|(other, elt)| {
+                if !other.contains(elt) { Some(elt) } else { None }
+            })
     }
 
     /// Visit the values representing the symmetric difference
@@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> {
     /// Visit the values representing the intersection
     pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>)
         -> SetAlgebraIter<'a, T> {
-        EnvFilterIterator{iter: self.iter(), env: other,
-                          filter: |elt, other| other.contains(elt) }
+        Repeat::new(other)
+            .zip(self.iter())
+            .filter_map(|(other, elt)| {
+                if other.contains(elt) { Some(elt) } else { None }
+            })
     }
 
     /// Visit the values representing the union
@@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
     }
 }
 
-// FIXME #7814: use std::iterator::FilterIterator
-/// Building block for Set operation iterators
-pub struct EnvFilterIterator<A, Env, I> {
-    priv env: Env,
-    priv filter: &'static fn(&A, Env) -> bool,
-    priv iter: I,
-}
-
-impl<'self, A, Env: Clone, I: Iterator<&'self A>> Iterator<&'self A>
-        for EnvFilterIterator<A, Env, I> {
-    #[inline]
-    fn next(&mut self) -> Option<&'self A> {
-        loop {
-            match self.iter.next() {
-                Some(elt) => if (self.filter)(elt, self.env.clone()) {
-                    return Some(elt)
-                },
-                None => return None,
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        let (_, upper) = self.iter.size_hint();
-        (0, upper)
-    }
-}
-
+// `Repeat` is used to feed the filter closure an explicit capture
+// of a reference to the other set
 /// Set operations iterator
 pub type SetAlgebraIter<'self, T> =
-    EnvFilterIterator<T, &'self HashSet<T>, HashSetIterator<'self, T>>;
+    FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T,
+              Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>;
 
 
 #[cfg(test)]
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 1c2fc5db443..07572d60917 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1042,7 +1042,7 @@ pub fn stdin() -> @Reader {
 
 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
     let f = do path.to_c_str().with_ref |pathbuf| {
-        do "r".to_c_str().with_ref |modebuf| {
+        do "rb".to_c_str().with_ref |modebuf| {
             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
         }
     };
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 0769aa6a764..56a0dca5667 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -82,6 +82,17 @@ pub trait DoubleEndedIteratorUtil {
 /// In the future these will be default methods instead of a utility trait.
 impl<A, T: DoubleEndedIterator<A>> DoubleEndedIteratorUtil for T {
     /// Flip the direction of the iterator
+    ///
+    /// The inverted iterator flips the ends on an iterator that can already
+    /// be iterated from the front and from the back.
+    ///
+    ///
+    /// If the iterator also implements RandomAccessIterator, the inverted
+    /// iterator is also random access, with the indices starting at the back
+    /// of the original iterator.
+    ///
+    /// Note: Random access with inverted indices still only applies to the first
+    /// `uint::max_value` elements of the original iterator.
     #[inline]
     fn invert(self) -> Invert<T> {
         Invert{iter: self}
@@ -106,6 +117,16 @@ impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Invert<T> {
     fn next_back(&mut self) -> Option<A> { self.iter.next() }
 }
 
+impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterator<A>
+    for Invert<T> {
+    #[inline]
+    fn indexable(&self) -> uint { self.iter.indexable() }
+    #[inline]
+    fn idx(&self, index: uint) -> Option<A> {
+        self.iter.idx(self.indexable() - index - 1)
+    }
+}
+
 /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
 /// implementations of the `Iterator` trait.
 ///
@@ -1555,6 +1576,39 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
     }
 }
 
+/// An iterator that repeats an element endlessly
+#[deriving(Clone, DeepClone)]
+pub struct Repeat<A> {
+    priv element: A
+}
+
+impl<A: Clone> Repeat<A> {
+    /// Create a new `Repeat` that enlessly repeats the element `elt`.
+    #[inline]
+    pub fn new(elt: A) -> Repeat<A> {
+        Repeat{element: elt}
+    }
+}
+
+impl<A: Clone> Iterator<A> for Repeat<A> {
+    #[inline]
+    fn next(&mut self) -> Option<A> { self.idx(0) }
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) { (uint::max_value, None) }
+}
+
+impl<A: Clone> DoubleEndedIterator<A> for Repeat<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> { self.idx(0) }
+}
+
+impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
+    #[inline]
+    fn indexable(&self) -> uint { uint::max_value }
+    #[inline]
+    fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -2018,6 +2072,17 @@ mod tests {
     }
 
     #[test]
+    fn test_random_access_invert() {
+        let xs = [1, 2, 3, 4, 5];
+        check_randacc_iter(xs.iter().invert(), xs.len());
+        let mut it = xs.iter().invert();
+        it.next();
+        it.next_back();
+        it.next();
+        check_randacc_iter(it, xs.len() - 3);
+    }
+
+    #[test]
     fn test_random_access_zip() {
         let xs = [1, 2, 3, 4, 5];
         let ys = [7, 9, 11];
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 537289c8dd6..c2a60e1c0e9 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -112,14 +112,14 @@ fn test_tls_multitask() {
         // TLS shouldn't carry over.
         assert!(get(my_key, |k| k.map(|&k| *k)).is_none());
         set(my_key, @~"child data");
-        assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) ==
+        assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) ==
                 ~"child data");
         // should be cleaned up for us
     }
     // Must work multiple times
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
 }
 
 #[test]
@@ -127,14 +127,14 @@ fn test_tls_overwrite() {
     static my_key: Key<@~str> = &Key;
     set(my_key, @~"first data");
     set(my_key, @~"next data"); // Shouldn't leak.
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"next data");
+    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"next data");
 }
 
 #[test]
 fn test_tls_pop() {
     static my_key: Key<@~str> = &Key;
     set(my_key, @~"weasel");
-    assert!(*(pop(my_key).get()) == ~"weasel");
+    assert!(*(pop(my_key).unwrap()) == ~"weasel");
     // Pop must remove the data from the map.
     assert!(pop(my_key).is_none());
 }
@@ -155,7 +155,7 @@ fn test_tls_modify() {
             None                 => fail!("missing value")
         }
     });
-    assert!(*(pop(my_key).get()) == ~"next data");
+    assert!(*(pop(my_key).unwrap()) == ~"next data");
 }
 
 #[test]
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 722af828d5c..7ab3c81b61f 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -726,4 +726,4 @@ mod bench {
             float::to_str(rng.gen());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 275a72d6ecc..86bc98e53fc 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -70,30 +70,6 @@ pub fn div_round(x: uint, y: uint) -> uint {
 ///
 pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
 
-///
-/// Iterate over the range [`lo`..`hi`), or stop when requested
-///
-/// # Arguments
-///
-/// * lo - The integer at which to start the loop (included)
-/// * hi - The integer at which to stop the loop (excluded)
-/// * it - A block to execute with each consecutive integer of the range.
-///        Return `true` to continue, `false` to stop.
-///
-/// # Return value
-///
-/// `true` If execution proceeded correctly, `false` if it was interrupted,
-/// that is if `it` returned `false` at any point.
-///
-pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool {
-    let mut i = lo;
-    while i < hi {
-        if (!it(i)) { return false; }
-        i += 1u;
-    }
-    return true;
-}
-
 impl iter::Times for uint {
     #[inline]
     ///
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 417251d3740..ea1bddcdb4b 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -47,7 +47,8 @@ use ops::Add;
 use util;
 use num::Zero;
 use iterator::Iterator;
-use str::StrSlice;
+use str::{StrSlice, OwnedStr};
+use to_str::ToStr;
 use clone::DeepClone;
 
 /// The option type
@@ -85,22 +86,37 @@ impl<T:Ord> Ord for Option<T> {
     }
 }
 
-impl<T:Clone+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
+impl<T: Add<T, T>> Add<Option<T>, Option<T>> for Option<T> {
     #[inline]
     fn add(&self, other: &Option<T>) -> Option<T> {
         match (&*self, &*other) {
             (&None, &None) => None,
-            (_, &None) => (*self).clone(),
-            (&None, _) => (*other).clone(),
+            (_, &None) => None,
+            (&None, _) => None,
             (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
         }
     }
 }
 
+// FIXME: #8242 implementing manually because deriving doesn't work for some reason
+impl<T: ToStr> ToStr for Option<T> {
+    fn to_str(&self) -> ~str {
+        match *self {
+            Some(ref x) => {
+                let mut s = ~"Some(";
+                s.push_str(x.to_str());
+                s.push_str(")");
+                s
+            }
+            None => ~"None"
+        }
+    }
+}
+
 impl<T> Option<T> {
     /// Return an iterator over the possibly contained value
     #[inline]
-    pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
+    pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
         match *self {
             Some(ref x) => OptionIterator{opt: Some(x)},
             None => OptionIterator{opt: None}
@@ -109,13 +125,19 @@ impl<T> Option<T> {
 
     /// Return a mutable iterator over the possibly contained value
     #[inline]
-    pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
+    pub fn mut_iter<'r>(&'r mut self) -> OptionIterator<&'r mut T> {
         match *self {
-            Some(ref mut x) => OptionMutIterator{opt: Some(x)},
-            None => OptionMutIterator{opt: None}
+            Some(ref mut x) => OptionIterator{opt: Some(x)},
+            None => OptionIterator{opt: None}
         }
     }
 
+    /// Return a consuming iterator over the possibly contained value
+    #[inline]
+    pub fn consume(self) -> OptionIterator<T> {
+        OptionIterator{opt: self}
+    }
+
     /// Returns true if the option equals `None`
     #[inline]
     pub fn is_none(&self) -> bool {
@@ -148,8 +170,7 @@ impl<T> Option<T> {
     /// Update an optional value by optionally running its content by reference
     /// through a function that returns an option.
     #[inline]
-    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
-                            -> Option<U> {
+    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
         match *self {
             Some(ref x) => f(x),
             None => None
@@ -159,8 +180,7 @@ impl<T> Option<T> {
     /// Update an optional value by optionally running its content by mut reference
     /// through a function that returns an option.
     #[inline]
-    pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>)
-                                -> Option<U> {
+    pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>) -> Option<U> {
         match *self {
             Some(ref mut x) => f(x),
             None => None
@@ -256,132 +276,105 @@ impl<T> Option<T> {
         }
     }
 
-    /**
-    Gets an immutable reference to the value inside an option.
-
-    # Failure
-
-    Fails if the value equals `None`
-
-    # Safety note
-
-    In general, because this function may fail, its use is discouraged
-    (calling `get` on `None` is akin to dereferencing a null pointer).
-    Instead, prefer to use pattern matching and handle the `None`
-    case explicitly.
-     */
+    /// Gets an immutable reference to the value inside an option.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the value equals `None`
+    ///
+    /// # Safety note
+    ///
+    /// In general, because this function may fail, its use is discouraged
+    /// (calling `get` on `None` is akin to dereferencing a null pointer).
+    /// Instead, prefer to use pattern matching and handle the `None`
+    /// case explicitly.
     #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
-          Some(ref x) => x,
-          None => fail!("option::get_ref `None`"),
+            Some(ref x) => x,
+            None => fail!("called `Option::get_ref()` on a `None` value"),
         }
     }
 
-    /**
-    Gets a mutable reference to the value inside an option.
-
-    # Failure
-
-    Fails if the value equals `None`
-
-    # Safety note
-
-    In general, because this function may fail, its use is discouraged
-    (calling `get` on `None` is akin to dereferencing a null pointer).
-    Instead, prefer to use pattern matching and handle the `None`
-    case explicitly.
-     */
+    /// Gets a mutable reference to the value inside an option.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the value equals `None`
+    ///
+    /// # Safety note
+    ///
+    /// In general, because this function may fail, its use is discouraged
+    /// (calling `get` on `None` is akin to dereferencing a null pointer).
+    /// Instead, prefer to use pattern matching and handle the `None`
+    /// case explicitly.
     #[inline]
     pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
         match *self {
-          Some(ref mut x) => x,
-          None => fail!("option::get_mut_ref `None`"),
+            Some(ref mut x) => x,
+            None => fail!("called `Option::get_mut_ref()` on a `None` value"),
         }
     }
 
+    /// Moves a value out of an option type and returns it.
+    ///
+    /// Useful primarily for getting strings, vectors and unique pointers out
+    /// of option types without copying them.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the value equals `None`.
+    ///
+    /// # Safety note
+    ///
+    /// In general, because this function may fail, its use is discouraged.
+    /// Instead, prefer to use pattern matching and handle the `None`
+    /// case explicitly.
     #[inline]
     pub fn unwrap(self) -> T {
-        /*!
-        Moves a value out of an option type and returns it.
-
-        Useful primarily for getting strings, vectors and unique pointers out
-        of option types without copying them.
-
-        # Failure
-
-        Fails if the value equals `None`.
-
-        # Safety note
-
-        In general, because this function may fail, its use is discouraged.
-        Instead, prefer to use pattern matching and handle the `None`
-        case explicitly.
-         */
         match self {
-          Some(x) => x,
-          None => fail!("option::unwrap `None`"),
+            Some(x) => x,
+            None => fail!("called `Option::unwrap()` on a `None` value"),
         }
     }
 
-    /**
-     * The option dance. Moves a value out of an option type and returns it,
-     * replacing the original with `None`.
-     *
-     * # Failure
-     *
-     * Fails if the value equals `None`.
-     */
+    /// The option dance. Moves a value out of an option type and returns it,
+    /// replacing the original with `None`.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the value equals `None`.
     #[inline]
     pub fn take_unwrap(&mut self) -> T {
-        if self.is_none() { fail!("option::take_unwrap `None`") }
+        if self.is_none() {
+            fail!("called `Option::take_unwrap()` on a `None` value")
+        }
         self.take().unwrap()
     }
 
-    /**
-     * Gets the value out of an option, printing a specified message on
-     * failure
-     *
-     * # Failure
-     *
-     * Fails if the value equals `None`
-     */
+    ///  Gets the value out of an option, printing a specified message on
+    ///  failure
+    ///
+    ///  # Failure
+    ///
+    ///  Fails if the value equals `None`
     #[inline]
     pub fn expect(self, reason: &str) -> T {
         match self {
-          Some(val) => val,
-          None => fail!(reason.to_owned()),
+            Some(val) => val,
+            None => fail!(reason.to_owned()),
         }
     }
 
-    /**
-    Gets the value out of an option
-
-    # Failure
-
-    Fails if the value equals `None`
-
-    # Safety note
-
-    In general, because this function may fail, its use is discouraged
-    (calling `get` on `None` is akin to dereferencing a null pointer).
-    Instead, prefer to use pattern matching and handle the `None`
-    case explicitly.
-    */
+    /// Returns the contained value or a default
     #[inline]
-    pub fn get(self) -> T {
+    pub fn unwrap_or_default(self, def: T) -> T {
         match self {
-          Some(x) => return x,
-          None => fail!("option::get `None`")
+            Some(x) => x,
+            None => def
         }
     }
 
-    /// Returns the contained value or a default
-    #[inline]
-    pub fn get_or_default(self, def: T) -> T {
-        match self { Some(x) => x, None => def }
-    }
-
     /// Applies a function zero or more times until the result is `None`.
     #[inline]
     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
@@ -395,12 +388,21 @@ impl<T> Option<T> {
 impl<T:Zero> Option<T> {
     /// Returns the contained value or zero (for this type)
     #[inline]
-    pub fn get_or_zero(self) -> T {
+    pub fn unwrap_or_zero(self) -> T {
         match self {
             Some(x) => x,
             None => Zero::zero()
         }
     }
+
+    /// Returns self or `Some(zero)` (for this type)
+    #[inline]
+    pub fn or_zero(self) -> Option<T> {
+        match self {
+            None => Some(Zero::zero()),
+            x => x
+        }
+    }
 }
 
 impl<T> Zero for Option<T> {
@@ -408,34 +410,18 @@ impl<T> Zero for Option<T> {
     fn is_zero(&self) -> bool { self.is_none() }
 }
 
-/// Immutable iterator over an `Option<A>`
-pub struct OptionIterator<'self, A> {
-    priv opt: Option<&'self A>
+/// An iterator that yields either one or zero elements
+pub struct OptionIterator<A> {
+    priv opt: Option<A>
 }
 
-impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
-    fn next(&mut self) -> Option<&'self A> {
-        util::replace(&mut self.opt, None)
-    }
-
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        match self.opt {
-            Some(_) => (1, Some(1)),
-            None => (0, Some(0)),
-        }
-    }
-}
-
-/// Mutable iterator over an `Option<A>`
-pub struct OptionMutIterator<'self, A> {
-    priv opt: Option<&'self mut A>
-}
-
-impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
-    fn next(&mut self) -> Option<&'self mut A> {
-        util::replace(&mut self.opt, None)
+impl<A> Iterator<A> for OptionIterator<A> {
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.opt.take()
     }
 
+    #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         match self.opt {
             Some(_) => (1, Some(1)),
@@ -450,7 +436,7 @@ mod tests {
     use util;
 
     #[test]
-    fn test_unwrap_ptr() {
+    fn test_get_ptr() {
         unsafe {
             let x = ~0;
             let addr_x: *int = ::cast::transmute(&*x);
@@ -462,7 +448,7 @@ mod tests {
     }
 
     #[test]
-    fn test_unwrap_str() {
+    fn test_get_str() {
         let x = ~"test";
         let addr_x = x.as_imm_buf(|buf, _len| buf);
         let opt = Some(x);
@@ -472,7 +458,7 @@ mod tests {
     }
 
     #[test]
-    fn test_unwrap_resource() {
+    fn test_get_resource() {
         struct R {
            i: @mut int,
         }
@@ -530,18 +516,18 @@ mod tests {
     }
 
     #[test]
-    fn test_get_or_zero() {
+    fn test_unwrap_or_zero() {
         let some_stuff = Some(42);
-        assert_eq!(some_stuff.get_or_zero(), 42);
+        assert_eq!(some_stuff.unwrap_or_zero(), 42);
         let no_stuff: Option<int> = None;
-        assert_eq!(no_stuff.get_or_zero(), 0);
+        assert_eq!(no_stuff.unwrap_or_zero(), 0);
     }
 
     #[test]
     fn test_filtered() {
         let some_stuff = Some(42);
         let modified_stuff = some_stuff.filtered(|&x| {x < 10});
-        assert_eq!(some_stuff.get(), 42);
+        assert_eq!(some_stuff.unwrap(), 42);
         assert!(modified_stuff.is_none());
     }
 
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 0e25d3dbe04..1f63a7c6041 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -574,7 +574,7 @@ pub fn tmpdir() -> Path {
 
     #[cfg(unix)]
     fn lookup() -> Path {
-        getenv_nonempty("TMPDIR").get_or_default(Path("/tmp"))
+        getenv_nonempty("TMPDIR").unwrap_or_default(Path("/tmp"))
     }
 
     #[cfg(windows)]
@@ -582,7 +582,7 @@ pub fn tmpdir() -> Path {
         getenv_nonempty("TMP").or(
             getenv_nonempty("TEMP").or(
                 getenv_nonempty("USERPROFILE").or(
-                   getenv_nonempty("WINDIR")))).get_or_default(Path("C:\\Windows"))
+                   getenv_nonempty("WINDIR")))).unwrap_or_default(Path("C:\\Windows"))
     }
 }
 
@@ -1788,7 +1788,7 @@ mod tests {
     fn test_self_exe_path() {
         let path = os::self_exe_path();
         assert!(path.is_some());
-        let path = path.get();
+        let path = path.unwrap();
         debug!(path.clone());
 
         // Hard to test this function
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 84d55c55c2f..a9e2e4c81a9 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -12,6 +12,7 @@
 
 use cast;
 use clone::Clone;
+use iterator::{range, Iterator};
 use option::{Option, Some, None};
 use unstable::intrinsics;
 use util::swap;
@@ -20,7 +21,6 @@ use util::swap;
 #[cfg(not(test))] use num::Int;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
-use uint;
 
 /// Calculate the offset from a pointer
 #[inline]
@@ -240,11 +240,10 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
         fail!("ptr::array_each_with_len failure: arr input is null pointer");
     }
     //let start_ptr = *arr;
-    uint::iterate(0, len, |e| {
+    for e in range(0, len) {
         let n = offset(arr, e as int);
         cb(*n);
-        true
-    });
+    }
     debug!("array_each_with_len: after iterate");
 }
 
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index b7d72c11ff7..4ef524d7715 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -533,7 +533,7 @@ impl<R: Rng> RngUtil for R {
 
     /// Choose an item randomly, failing if values is empty
     fn choose<T:Clone>(&mut self, values: &[T]) -> T {
-        self.choose_option(values).get()
+        self.choose_option(values).unwrap()
     }
 
     /// Choose Some(item) randomly, returning None if values is empty
@@ -549,7 +549,7 @@ impl<R: Rng> RngUtil for R {
      * the weights is 0
      */
     fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
-        self.choose_weighted_option(v).get()
+        self.choose_weighted_option(v).unwrap()
     }
 
     /**
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 7a578465841..91f42edf0ae 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -16,27 +16,31 @@ use clone::Clone;
 use cmp::Eq;
 use either;
 use iterator::Iterator;
-use option::{None, Option, Some};
+use option::{None, Option, Some, OptionIterator};
 use vec;
 use vec::{OwnedVector, ImmutableVector};
 use container::Container;
-
-/// The result type
+use to_str::ToStr;
+use str::StrSlice;
+
+/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
+///
+/// In order to provide informative error messages, `E` is reqired to implement `ToStr`.
+/// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
+/// all possible errors cases.
 #[deriving(Clone, Eq)]
-pub enum Result<T, U> {
+pub enum Result<T, E> {
     /// Contains the successful result value
     Ok(T),
     /// Contains the error value
-    Err(U)
+    Err(E)
 }
 
-impl<T, E> Result<T, E> {
-    /**
-     * Convert to the `either` type
-     *
-     * `Ok` result variants are converted to `either::Right` variants, `Err`
-     * result variants are converted to `either::Left`.
-     */
+impl<T, E: ToStr> Result<T, E> {
+    /// Convert to the `either` type
+    ///
+    /// `Ok` result variants are converted to `either::Right` variants, `Err`
+    /// result variants are converted to `either::Left`.
     #[inline]
     pub fn to_either(self)-> either::Either<E, T>{
         match self {
@@ -45,18 +49,16 @@ impl<T, E> Result<T, E> {
         }
     }
 
-    /**
-     * Get a reference to the value out of a successful result
-     *
-     * # Failure
-     *
-     * If the result is an error
-     */
+    /// Get a reference to the value out of a successful result
+    ///
+    /// # Failure
+    ///
+    /// If the result is an error
     #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
             Ok(ref t) => t,
-            Err(ref e) => fail!("get_ref called on `Err` result: %?", *e),
+            Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: %s", e.to_str()),
         }
     }
 
@@ -75,76 +77,90 @@ impl<T, E> Result<T, E> {
         !self.is_ok()
     }
 
-    /**
-     * Call a method based on a previous result
-     *
-     * If `self` is `Ok` then the value is extracted and passed to `op`
-     * whereupon `op`s result is returned. if `self` is `Err` then it is
-     * immediately returned. This function can be used to compose the results
-     * of two functions.
-     *
-     * Example:
-     *
-     *     do read_file(file).iter |buf| {
-     *         print_buf(buf)
-     *     }
-     */
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Ok` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is returned. if `self` is `Err` then it is
+    /// immediately returned. This function can be used to compose the results
+    /// of two functions.
+    ///
+    /// Example:
+    ///
+    ///     for buf in read_file(file) {
+    ///         print_buf(buf)
+    ///     }
     #[inline]
-    pub fn iter(&self, f: &fn(&T)) {
+    pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
         match *self {
-            Ok(ref t) => f(t),
-            Err(_) => (),
-        }
+            Ok(ref t) => Some(t),
+            Err(*) => None,
+        }.consume()
     }
 
-    /**
-     * Call a method based on a previous result
-     *
-     * If `self` is `Err` then the value is extracted and passed to `op`
-     * whereupon `op`s result is returned. if `self` is `Ok` then it is
-     * immediately returned.  This function can be used to pass through a
-     * successful result while handling an error.
-     */
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Err` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is returned. if `self` is `Ok` then it is
+    /// immediately returned.  This function can be used to pass through a
+    /// successful result while handling an error.
     #[inline]
-    pub fn iter_err(&self, f: &fn(&E)) {
+    pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
         match *self {
-            Ok(_) => (),
-            Err(ref e) => f(e),
-        }
+            Ok(*) => None,
+            Err(ref t) => Some(t),
+        }.consume()
     }
 
-    /// Unwraps a result, assuming it is an `Ok(T)`
+    /// Unwraps a result, yielding the content of an `Ok`.
+    /// Fails if the value is a `Err` with an error message derived
+    /// from `E`'s `ToStr` implementation.
     #[inline]
     pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
-            Err(_) => fail!("unwrap called on an `Err` result"),
+            Err(e) => fail!("called `Result::unwrap()` on `Err` value: %s", e.to_str()),
         }
     }
 
-    /// Unwraps a result, assuming it is an `Err(U)`
+    /// Unwraps a result, yielding the content of an `Err`.
+    /// Fails if the value is a `Ok`.
     #[inline]
     pub fn unwrap_err(self) -> E {
+        self.expect_err("called `Result::unwrap_err()` on `Ok` value")
+    }
+
+    /// Unwraps a result, yielding the content of an `Ok`.
+    /// Fails if the value is a `Err` with a custom failure message.
+    #[inline]
+    pub fn expect(self, reason: &str) -> T {
+        match self {
+            Ok(t) => t,
+            Err(_) => fail!(reason.to_owned()),
+        }
+    }
+
+    /// Unwraps a result, yielding the content of an `Err`
+    /// Fails if the value is a `Ok` with a custom failure message.
+    #[inline]
+    pub fn expect_err(self, reason: &str) -> E {
         match self {
             Err(e) => e,
-            Ok(_) => fail!("unwrap called on an `Ok` result"),
+            Ok(_) => fail!(reason.to_owned()),
         }
     }
 
-    /**
-     * Call a method based on a previous result
-     *
-     * If `self` is `Ok` then the value is extracted and passed to `op`
-     * whereupon `op`s result is returned. if `self` is `Err` then it is
-     * immediately returned. This function can be used to compose the results
-     * of two functions.
-     *
-     * Example:
-     *
-     *     let res = do read_file(file) |buf| {
-     *         Ok(parse_bytes(buf))
-     *     };
-     */
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Ok` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is returned. if `self` is `Err` then it is
+    /// immediately returned. This function can be used to compose the results
+    /// of two functions.
+    ///
+    /// Example:
+    ///
+    ///     let res = do read_file(file) |buf| {
+    ///         Ok(parse_bytes(buf))
+    ///     };
     #[inline]
     pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
         match self {
@@ -153,14 +169,12 @@ impl<T, E> Result<T, E> {
         }
     }
 
-    /**
-     * Call a function based on a previous result
-     *
-     * If `self` is `Err` then the value is extracted and passed to `op`
-     * whereupon `op`s result is returned. if `self` is `Ok` then it is
-     * immediately returned.  This function can be used to pass through a
-     * successful result while handling an error.
-     */
+    /// Call a function based on a previous result
+    ///
+    /// If `self` is `Err` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is returned. if `self` is `Ok` then it is
+    /// immediately returned.  This function can be used to pass through a
+    /// successful result while handling an error.
     #[inline]
     pub fn chain_err<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
         match self {
@@ -170,32 +184,15 @@ impl<T, E> Result<T, E> {
     }
 }
 
-impl<T: Clone, E> Result<T, E> {
-    /**
-     * Get the value out of a successful result
-     *
-     * # Failure
-     *
-     * If the result is an error
-     */
-    #[inline]
-    pub fn get(&self) -> T {
-        match *self {
-            Ok(ref t) => t.clone(),
-            Err(ref e) => fail!("get called on `Err` result: %?", *e),
-        }
-    }
-
-    /**
-     * Call a method based on a previous result
-     *
-     * If `self` is `Err` then the value is extracted and passed to `op`
-     * whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
-     * `Ok` then it is immediately returned.  This function can be used to pass
-     * through a successful result while handling an error.
-     */
+impl<T: Clone, E: ToStr> Result<T, E> {
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Err` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
+    /// `Ok` then it is immediately returned.  This function can be used to pass
+    /// through a successful result while handling an error.
     #[inline]
-    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
+    pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
         match *self {
             Ok(ref t) => Ok(t.clone()),
             Err(ref e) => Err(op(e))
@@ -203,62 +200,57 @@ impl<T: Clone, E> Result<T, E> {
     }
 }
 
-impl<T, E: Clone> Result<T, E> {
-    /**
-     * Get the value out of an error result
-     *
-     * # Failure
-     *
-     * If the result is not an error
-     */
+impl<T, E: Clone + ToStr> Result<T, E> {
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Ok` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
+    /// `Err` then it is immediately returned.  This function can be used to
+    /// compose the results of two functions.
+    ///
+    /// Example:
+    ///
+    ///     let res = do read_file(file).map |buf| {
+    ///         parse_bytes(buf)
+    ///     };
     #[inline]
-    pub fn get_err(&self) -> E {
+    pub fn map<U>(&self, op: &fn(&T) -> U) -> Result<U,E> {
         match *self {
-            Err(ref e) => e.clone(),
-            Ok(_) => fail!("get_err called on `Ok` result")
+            Ok(ref t) => Ok(op(t)),
+            Err(ref e) => Err(e.clone())
         }
     }
+}
 
-    /**
-     * Call a method based on a previous result
-     *
-     * If `self` is `Ok` then the value is extracted and passed to `op`
-     * whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
-     * `Err` then it is immediately returned.  This function can be used to
-     * compose the results of two functions.
-     *
-     * Example:
-     *
-     *     let res = do read_file(file).map |buf| {
-     *         parse_bytes(buf)
-     *     };
-     */
-    #[inline]
-    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
-        match *self {
-            Ok(ref t) => Ok(op(t)),
-            Err(ref e) => Err(e.clone())
+#[inline]
+#[allow(missing_doc)]
+pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
+                               op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
+    match *o_t {
+        None => Ok(None),
+        Some(ref t) => match op(t) {
+            Ok(v) => Ok(Some(v)),
+            Err(e) => Err(e)
         }
     }
 }
 
-/**
- * Maps each element in the vector `ts` using the operation `op`.  Should an
- * error occur, no further mappings are performed and the error is returned.
- * Should no error occur, a vector containing the result of each map is
- * returned.
- *
- * Here is an example which increments every integer in a vector,
- * checking for overflow:
- *
- *     fn inc_conditionally(x: uint) -> result<uint,str> {
- *         if x == uint::max_value { return Err("overflow"); }
- *         else { return Ok(x+1u); }
- *     }
- *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
- *         assert!(incd == ~[2u, 3u, 4u]);
- *     }
- */
+// FIXME: #8228 Replaceable by an external iterator?
+/// Maps each element in the vector `ts` using the operation `op`.  Should an
+/// error occur, no further mappings are performed and the error is returned.
+/// Should no error occur, a vector containing the result of each map is
+/// returned.
+///
+/// Here is an example which increments every integer in a vector,
+/// checking for overflow:
+///
+///     fn inc_conditionally(x: uint) -> result<uint,str> {
+///         if x == uint::max_value { return Err("overflow"); }
+///         else { return Ok(x+1u); }
+///     }
+///     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
+///         assert!(incd == ~[2u, 3u, 4u]);
+///     }
 #[inline]
 pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
                       -> Result<~[V],U> {
@@ -272,36 +264,17 @@ pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
     return Ok(vs);
 }
 
+// FIXME: #8228 Replaceable by an external iterator?
+/// Same as map, but it operates over two parallel vectors.
+///
+/// A precondition is used here to ensure that the vectors are the same
+/// length.  While we do not often use preconditions in the standard
+/// library, a precondition is used here because result::t is generally
+/// used in 'careful' code contexts where it is both appropriate and easy
+/// to accommodate an error like the vectors being of different lengths.
 #[inline]
-#[allow(missing_doc)]
-pub fn map_opt<T,
-               U,
-               V>(
-               o_t: &Option<T>,
-               op: &fn(&T) -> Result<V,U>)
-               -> Result<Option<V>,U> {
-    match *o_t {
-        None => Ok(None),
-        Some(ref t) => match op(t) {
-            Ok(v) => Ok(Some(v)),
-            Err(e) => Err(e)
-        }
-    }
-}
-
-/**
- * Same as map, but it operates over two parallel vectors.
- *
- * A precondition is used here to ensure that the vectors are the same
- * length.  While we do not often use preconditions in the standard
- * library, a precondition is used here because result::t is generally
- * used in 'careful' code contexts where it is both appropriate and easy
- * to accommodate an error like the vectors being of different lengths.
- */
-#[inline]
-pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
-                op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
-
+pub fn map_vec2<S, T, U: ToStr, V>(ss: &[S], ts: &[T],
+                                   op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
     assert!(vec::same_length(ss, ts));
     let n = ts.len();
     let mut vs = vec::with_capacity(n);
@@ -316,15 +289,13 @@ pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
     return Ok(vs);
 }
 
-/**
- * Applies op to the pairwise elements from `ss` and `ts`, aborting on
- * error.  This could be implemented using `map_zip()` but it is more efficient
- * on its own as no result vector is built.
- */
+// FIXME: #8228 Replaceable by an external iterator?
+/// Applies op to the pairwise elements from `ss` and `ts`, aborting on
+/// error.  This could be implemented using `map_zip()` but it is more efficient
+/// on its own as no result vector is built.
 #[inline]
-pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
-                         op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
-
+pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
+                                 op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
     assert!(vec::same_length(ss, ts));
     let n = ts.len();
     let mut i = 0u;
@@ -353,32 +324,36 @@ mod tests {
 
     #[test]
     pub fn chain_success() {
-        assert_eq!(op1().chain(op2).get(), 667u);
+        assert_eq!(op1().chain(op2).unwrap(), 667u);
     }
 
     #[test]
     pub fn chain_failure() {
-        assert_eq!(op3().chain( op2).get_err(), ~"sadface");
+        assert_eq!(op3().chain( op2).unwrap_err(), ~"sadface");
     }
 
     #[test]
     pub fn test_impl_iter() {
         let mut valid = false;
-        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
+        let okval = Ok::<~str, ~str>(~"a");
+        do okval.iter().next().map |_| { valid = true; };
         assert!(valid);
 
-        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
+        let errval = Err::<~str, ~str>(~"b");
+        do errval.iter().next().map |_| { valid = false; };
         assert!(valid);
     }
 
     #[test]
     pub fn test_impl_iter_err() {
         let mut valid = true;
-        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
+        let okval = Ok::<~str, ~str>(~"a");
+        do okval.iter_err().next().map |_| { valid = false };
         assert!(valid);
 
         valid = false;
-        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
+        let errval = Err::<~str, ~str>(~"b");
+        do errval.iter_err().next().map |_| { valid = true };
         assert!(valid);
     }
 
diff --git a/src/libstd/rt/io/flate.rs b/src/libstd/rt/io/flate.rs
index e57b80658ee..16bca850fd2 100644
--- a/src/libstd/rt/io/flate.rs
+++ b/src/libstd/rt/io/flate.rs
@@ -10,7 +10,7 @@
 
 //! Some various other I/O types
 
-// NOTE: These ultimately belong somewhere else
+// FIXME(#3660): should move to libextra
 
 use prelude::*;
 use super::*;
@@ -115,7 +115,7 @@ mod test {
         let mem_reader = MemReader::new(buf);
         let mut inflate_reader = InflateReader::new(mem_reader);
         let mut out_bytes = [0, .. 100];
-        let bytes_read = inflate_reader.read(out_bytes).get();
+        let bytes_read = inflate_reader.read(out_bytes).unwrap();
         assert_eq!(bytes_read, in_bytes.len());
         let out_msg = str::from_bytes(out_bytes);
         assert!(in_msg == out_msg);
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index 838c2d86c9f..c980dc9d73e 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -243,6 +243,8 @@ Out of scope
 */
 
 use prelude::*;
+use to_str::ToStr;
+use str::{StrSlice, OwnedStr};
 
 // Reexports
 pub use self::stdio::stdin;
@@ -334,6 +336,20 @@ pub struct IoError {
     detail: Option<~str>
 }
 
+// FIXME: #8242 implementing manually because deriving doesn't work for some reason
+impl ToStr for IoError {
+    fn to_str(&self) -> ~str {
+        let mut s = ~"IoError { kind: ";
+        s.push_str(self.kind.to_str());
+        s.push_str(", desc: ");
+        s.push_str(self.desc);
+        s.push_str(", detail: ");
+        s.push_str(self.detail.to_str());
+        s.push_str(" }");
+        s
+    }
+}
+
 #[deriving(Eq)]
 pub enum IoErrorKind {
     PreviousIoError,
@@ -348,6 +364,24 @@ pub enum IoErrorKind {
     BrokenPipe
 }
 
+// FIXME: #8242 implementing manually because deriving doesn't work for some reason
+impl ToStr for IoErrorKind {
+    fn to_str(&self) -> ~str {
+        match *self {
+            PreviousIoError => ~"PreviousIoError",
+            OtherIoError => ~"OtherIoError",
+            EndOfFile => ~"EndOfFile",
+            FileNotFound => ~"FileNotFound",
+            PermissionDenied => ~"PermissionDenied",
+            ConnectionFailed => ~"ConnectionFailed",
+            Closed => ~"Closed",
+            ConnectionRefused => ~"ConnectionRefused",
+            ConnectionReset => ~"ConnectionReset",
+            BrokenPipe => ~"BrokenPipe"
+        }
+    }
+}
+
 // XXX: Can't put doc comments on macros
 // Raised by `I/O` operations on error.
 condition! {
@@ -505,4 +539,4 @@ pub fn placeholder_error() -> IoError {
         desc: "Placeholder error. You shouldn't be seeing this",
         detail: None
     }
-}
\ No newline at end of file
+}
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index deec8dd37a6..3372c13b877 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -193,6 +193,10 @@ impl BlockedTask {
 
     /// Create a blocked task, unless the task was already killed.
     pub fn try_block(mut task: ~Task) -> Either<~Task, BlockedTask> {
+        // NB: As an optimization, we could give a free pass to being unkillable
+        // to tasks whose taskgroups haven't been initialized yet, but that
+        // introduces complications with select() and with the test cases below,
+        // and it's not clear the uncommon performance boost is worth it.
         if task.death.unkillable > 0 {
             Right(Unkillable(task))
         } else {
@@ -205,11 +209,10 @@ impl BlockedTask {
                 let flag_arc = match task.death.spare_kill_flag.take() {
                     Some(spare_flag) => spare_flag,
                     None => {
-                        // FIXME(#7544): Uncomment this when terminate_current_task
-                        // stops being *terrible*. That's the only place that violates
-                        // the assumption of "becoming unkillable will fail if the
-                        // task was killed".
-                        // rtassert!(task.unwinder.unwinding);
+                        // A task that kills us won't have a spare kill flag to
+                        // give back to us, so we restore it ourselves here. This
+                        // situation should only arise when we're already failing.
+                        rtassert!(task.unwinder.unwinding);
                         (*task.death.kill_handle.get_ref().get()).killed.clone()
                     }
                 };
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 33e83fd9040..760ca8a9ada 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -365,7 +365,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
 
         rtdebug!("about to create the main scheduler task");
 
-        let mut main_sched = main_sched.get();
+        let mut main_sched = main_sched.unwrap();
 
         let home = Sched(main_sched.make_handle());
         let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index cb949edd7bb..4c5e4bdc3c1 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -465,10 +465,10 @@ mod test {
         do run_in_newsched_task() {
             static key: local_data::Key<@~str> = &local_data::Key;
             local_data::set(key, @~"data");
-            assert!(*local_data::get(key, |k| k.map(|&k| *k)).get() == ~"data");
+            assert!(*local_data::get(key, |k| k.map(|&k| *k)).unwrap() == ~"data");
             static key2: local_data::Key<@~str> = &local_data::Key;
             local_data::set(key2, @~"data");
-            assert!(*local_data::get(key2, |k| k.map(|&k| *k)).get() == ~"data");
+            assert!(*local_data::get(key2, |k| k.map(|&k| *k)).unwrap() == ~"data");
         }
     }
 
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index 2427da01a0c..8b5215ae969 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -154,7 +154,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
 
     do run_in_bare_thread {
         let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
-            Some(nstr) => FromStr::from_str(nstr).get(),
+            Some(nstr) => FromStr::from_str(nstr).unwrap(),
             None => {
                 // Using more threads than cores in test code
                 // to force the OS to preempt them frequently.
@@ -362,7 +362,7 @@ pub fn stress_factor() -> uint {
     use os::getenv;
 
     match getenv("RUST_RT_STRESS") {
-        Some(val) => uint::from_str(val).get(),
+        Some(val) => uint::from_str(val).unwrap(),
         None => 1
     }
 }
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index a1169954688..40e5c8d4bf1 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -31,7 +31,7 @@ pub fn num_cpus() -> uint {
 /// either `RUST_THREADS` or `num_cpus`.
 pub fn default_sched_threads() -> uint {
     match os::getenv("RUST_THREADS") {
-        Some(nstr) => FromStr::from_str(nstr).get(),
+        Some(nstr) => FromStr::from_str(nstr).unwrap(),
         None => num_cpus()
     }
 }
@@ -118,4 +118,4 @@ pub fn get_exit_status() -> int {
     extern {
         fn rust_get_exit_status_newrt() -> libc::uintptr_t;
     }
-}
\ No newline at end of file
+}
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
index 67d3bbef8a9..fd3042899f6 100644
--- a/src/libstd/rt/uv/net.rs
+++ b/src/libstd/rt/uv/net.rs
@@ -108,7 +108,7 @@ fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T)
                             "" => ~[],
                             // IPv4-Mapped/Compatible IPv6 Address?
                             s if s.find('.').is_some() => {
-                                let i = s.rfind(':').get_or_default(-1);
+                                let i = s.rfind(':').unwrap_or_default(-1);
 
                                 let b = s.slice(i + 1, s.len()); // the ipv4 part
 
@@ -614,7 +614,7 @@ mod test {
             do tcp_watcher.connect(addr) |stream_watcher, status| {
                 rtdebug!("tcp_watcher.connect!");
                 assert!(status.is_some());
-                assert_eq!(status.get().name(), ~"ECONNREFUSED");
+                assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
                 stream_watcher.close(||());
             }
             loop_.run();
@@ -632,7 +632,7 @@ mod test {
             do tcp_watcher.connect(addr) |stream_watcher, status| {
                 rtdebug!("tcp_watcher.connect!");
                 assert!(status.is_some());
-                assert_eq!(status.get().name(), ~"ECONNREFUSED");
+                assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
                 stream_watcher.close(||());
             }
             loop_.run();
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 01d01de54ef..038ebad3540 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -278,7 +278,7 @@ impl IoFactory for UvIoFactory {
                     rtdebug!("status is some");
                     let task_cell = Cell::new(task_cell.take());
                     do stream_watcher.close {
-                        let res = Err(uv_error_to_io_error(status.get()));
+                        let res = Err(uv_error_to_io_error(status.unwrap()));
                         unsafe { (*result_cell_ptr).put_back(res); }
                         let scheduler = Local::take::<Scheduler>();
                         scheduler.resume_blocked_task_immediately(task_cell.take());
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 60148e1432c..7c3a3ca8619 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -59,7 +59,7 @@ pub fn from_bytes(vv: &[u8]) -> ~str {
     use str::not_utf8::cond;
 
     if !is_utf8(vv) {
-        let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
+        let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).unwrap();
         cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
                         first_bad_byte as uint))
     } else {
@@ -76,7 +76,7 @@ pub fn from_bytes_owned(vv: ~[u8]) -> ~str {
     use str::not_utf8::cond;
 
     if !is_utf8(vv) {
-        let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
+        let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).unwrap();
         cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
                         first_bad_byte as uint))
     } else {
@@ -1029,7 +1029,7 @@ pub mod raw {
     /// If end is greater than the length of the string.
     #[cfg(stage0)]
     #[inline]
-    pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
+    pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
         do s.as_imm_buf |sbuf, n| {
              assert!((begin <= end));
              assert!((end <= n));
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index f7a943f8d2f..225a4b8cfd2 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -926,7 +926,7 @@ fn test_named_task() {
         t.name(~"ada lovelace");
         do t.spawn {
             do with_task_name |name| {
-                assert!(name.get() == "ada lovelace");
+                assert!(name.unwrap() == "ada lovelace");
             }
         }
     }
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 3bf2f255f57..527b20b0e90 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -568,7 +568,8 @@ impl RuntimeGlue {
                 let me = Local::unsafe_borrow::<Task>();
                 blk(match (*me).taskgroup {
                     None => {
-                        // Main task, doing first spawn ever. Lazily initialize.
+                        // First task in its (unlinked/unsupervised) taskgroup.
+                        // Lazily initialize.
                         let mut members = TaskSet::new();
                         let my_handle = (*me).death.kill_handle.get_ref().clone();
                         members.insert(NewTask(my_handle));
@@ -591,37 +592,46 @@ impl RuntimeGlue {
     }
 }
 
+// Returns 'None' in the case where the child's TG should be lazily initialized.
 fn gen_child_taskgroup(linked: bool, supervised: bool)
-    -> (TaskGroupArc, AncestorList, bool) {
-    do RuntimeGlue::with_my_taskgroup |spawner_group| {
-        let ancestors = AncestorList(spawner_group.ancestors.map(|x| x.clone()));
-        if linked {
-            // Child is in the same group as spawner.
-            // Child's ancestors are spawner's ancestors.
-            // Propagate main-ness.
-            (spawner_group.tasks.clone(), ancestors, spawner_group.is_main)
-        } else {
-            // Child is in a separate group from spawner.
-            let g = Exclusive::new(Some(TaskGroupData {
-                members:     TaskSet::new(),
-                descendants: TaskSet::new(),
-            }));
-            let a = if supervised {
-                let new_generation = incr_generation(&ancestors);
-                assert!(new_generation < uint::max_value);
-                // Child's ancestors start with the spawner.
-                // Build a new node in the ancestor list.
-                AncestorList(Some(Exclusive::new(AncestorNode {
-                    generation: new_generation,
-                    parent_group: spawner_group.tasks.clone(),
-                    ancestors: ancestors,
-                })))
+    -> Option<(TaskGroupArc, AncestorList, bool)> {
+    // FIXME(#7544): Not safe to lazily initialize in the old runtime. Remove
+    // this context check once 'spawn_raw_oldsched' is gone.
+    if context() == OldTaskContext || linked || supervised {
+        // with_my_taskgroup will lazily initialize the parent's taskgroup if
+        // it doesn't yet exist. We don't want to call it in the unlinked case.
+        do RuntimeGlue::with_my_taskgroup |spawner_group| {
+            let ancestors = AncestorList(spawner_group.ancestors.map(|x| x.clone()));
+            if linked {
+                // Child is in the same group as spawner.
+                // Child's ancestors are spawner's ancestors.
+                // Propagate main-ness.
+                Some((spawner_group.tasks.clone(), ancestors, spawner_group.is_main))
             } else {
-                // Child has no ancestors.
-                AncestorList(None)
-            };
-            (g, a, false)
+                // Child is in a separate group from spawner.
+                let g = Exclusive::new(Some(TaskGroupData {
+                    members:     TaskSet::new(),
+                    descendants: TaskSet::new(),
+                }));
+                let a = if supervised {
+                    let new_generation = incr_generation(&ancestors);
+                    assert!(new_generation < uint::max_value);
+                    // Child's ancestors start with the spawner.
+                    // Build a new node in the ancestor list.
+                    AncestorList(Some(Exclusive::new(AncestorNode {
+                        generation: new_generation,
+                        parent_group: spawner_group.tasks.clone(),
+                        ancestors: ancestors,
+                    })))
+                } else {
+                    // Child has no ancestors.
+                    AncestorList(None)
+                };
+                Some((g, a, false))
+            }
         }
+    } else {
+        None
     }
 }
 
@@ -670,20 +680,24 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
 
     let child_wrapper: ~fn() = || {
         // Child task runs this code.
-        let child_data = Cell::new(child_data.take()); // :(
-        let enlist_success = do Local::borrow::<Task, bool> |me| {
-            let (child_tg, ancestors, is_main) = child_data.take();
-            let mut ancestors = ancestors;
-            // FIXME(#7544): Optimize out the xadd in this clone, somehow.
-            let handle = me.death.kill_handle.get_ref().clone();
-            // Atomically try to get into all of our taskgroups.
-            if enlist_many(NewTask(handle), &child_tg, &mut ancestors) {
-                // Got in. We can run the provided child body, and can also run
-                // the taskgroup's exit-time-destructor afterward.
-                me.taskgroup = Some(Taskgroup(child_tg, ancestors, is_main, None));
-                true
-            } else {
-                false
+
+        // If child data is 'None', the enlist is vacuously successful.
+        let enlist_success = do child_data.take().map_consume_default(true) |child_data| {
+            let child_data = Cell::new(child_data); // :(
+            do Local::borrow::<Task, bool> |me| {
+                let (child_tg, ancestors, is_main) = child_data.take();
+                let mut ancestors = ancestors;
+                // FIXME(#7544): Optimize out the xadd in this clone, somehow.
+                let handle = me.death.kill_handle.get_ref().clone();
+                // Atomically try to get into all of our taskgroups.
+                if enlist_many(NewTask(handle), &child_tg, &mut ancestors) {
+                    // Got in. We can run the provided child body, and can also run
+                    // the taskgroup's exit-time-destructor afterward.
+                    me.taskgroup = Some(Taskgroup(child_tg, ancestors, is_main, None));
+                    true
+                } else {
+                    false
+                }
             }
         };
         // Should be run after the local-borrowed task is returned.
@@ -749,7 +763,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
                 let join_task = join_task_cell.take();
 
                 let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
-                    rtdebug!("boostraping a 1:1 scheduler");
+                    rtdebug!("bootstrapping a 1:1 scheduler");
                 };
                 new_sched.bootstrap(bootstrap_task);
 
@@ -793,7 +807,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
 fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
 
     let (child_tg, ancestors, is_main) =
-        gen_child_taskgroup(opts.linked, opts.supervised);
+        gen_child_taskgroup(opts.linked, opts.supervised).expect("old runtime needs TG");
 
     unsafe {
         let child_data = Cell::new((child_tg, ancestors, f));
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 679d36b87f1..6f61d29780f 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -14,6 +14,7 @@ use prelude::*;
 use iterator::{IteratorUtil, FromIterator, Extendable};
 use uint;
 use util::{swap, replace};
+use vec;
 
 // FIXME: #5244: need to manually update the TrieNode constructor
 static SHIFT: uint = 4;
@@ -146,6 +147,15 @@ impl<T> TrieMap<T> {
     pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
         self.each_reverse(|_, v| f(v))
     }
+
+    /// Get an iterator over the key-value pairs in the map
+    pub fn iter<'a>(&'a self) -> TrieMapIterator<'a, T> {
+        TrieMapIterator {
+            stack: ~[self.root.children.iter()],
+            remaining_min: self.length,
+            remaining_max: self.length
+        }
+    }
 }
 
 impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
@@ -217,6 +227,12 @@ impl TrieSet {
     pub fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool {
         self.map.each_key_reverse(f)
     }
+
+    /// Get an iterator over the values in the set
+    #[inline]
+    pub fn iter<'a>(&'a self) -> TrieSetIterator<'a> {
+        TrieSetIterator{iter: self.map.iter()}
+    }
 }
 
 impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
@@ -366,6 +382,61 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
     return ret;
 }
 
+/// Forward iterator over a map
+pub struct TrieMapIterator<'self, T> {
+    priv stack: ~[vec::VecIterator<'self, Child<T>>],
+    priv remaining_min: uint,
+    priv remaining_max: uint
+}
+
+impl<'self, T> Iterator<(uint, &'self T)> for TrieMapIterator<'self, T> {
+    fn next(&mut self) -> Option<(uint, &'self T)> {
+        while !self.stack.is_empty() {
+            match self.stack[self.stack.len() - 1].next() {
+                None => {
+                    self.stack.pop();
+                }
+                Some(ref child) => {
+                    match **child {
+                        Internal(ref node) => {
+                            self.stack.push(node.children.iter());
+                        }
+                        External(key, ref value) => {
+                            self.remaining_max -= 1;
+                            if self.remaining_min > 0 {
+                                self.remaining_min -= 1;
+                            }
+                            return Some((key, value));
+                        }
+                        Nothing => {}
+                    }
+                }
+            }
+        }
+        return None;
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (self.remaining_min, Some(self.remaining_max))
+    }
+}
+
+/// Forward iterator over a set
+pub struct TrieSetIterator<'self> {
+    priv iter: TrieMapIterator<'self, ()>
+}
+
+impl<'self> Iterator<uint> for TrieSetIterator<'self> {
+    fn next(&mut self) -> Option<uint> {
+        do self.iter.next().map |&(key, _)| { key }
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.iter.size_hint()
+    }
+}
+
 #[cfg(test)]
 pub fn check_integrity<T>(trie: &TrieNode<T>) {
     assert!(trie.count != 0);
@@ -553,6 +624,29 @@ mod test_map {
             assert_eq!(map.find(&k), Some(&v));
         }
     }
+
+    #[test]
+    fn test_iteration() {
+        let empty_map : TrieMap<uint> = TrieMap::new();
+        assert_eq!(empty_map.iter().next(), None);
+
+        let first = uint::max_value - 10000;
+        let last = uint::max_value;
+
+        let mut map = TrieMap::new();
+        do uint::range_rev(last, first) |x| {
+            map.insert(x, x / 2);
+            true
+        };
+
+        let mut i = 0;
+        for (k, &v) in map.iter() {
+            assert_eq!(k, first + i);
+            assert_eq!(v, k / 2);
+            i += 1;
+        }
+        assert_eq!(i, last - first);
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index f037aa2b7e7..0259b547ab3 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -195,10 +195,8 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> ~[A] {
  *             onto the vector being constructed.
  */
 #[inline]
-pub fn build_sized_opt<A>(size: Option<uint>,
-                          builder: &fn(push: &fn(v: A)))
-                       -> ~[A] {
-    build_sized(size.get_or_default(4), builder)
+pub fn build_sized_opt<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> ~[A] {
+    build_sized(size.unwrap_or_default(4), builder)
 }
 
 /// An iterator over the slices of a vector separated by elements that
@@ -481,6 +479,7 @@ pub fn each_permutation<T:Clone>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
 
 /// An iterator over the (overlapping) slices of length `size` within
 /// a vector.
+#[deriving(Clone)]
 pub struct WindowIter<'self, T> {
     priv v: &'self [T],
     priv size: uint
@@ -500,6 +499,10 @@ impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
 
 /// An iterator over a vector in (non-overlapping) chunks (`size`
 /// elements at a time).
+///
+/// When the vector len is not evenly divided by the chunk size,
+/// the last slice of the iteration will be the remainer.
+#[deriving(Clone)]
 pub struct ChunkIter<'self, T> {
     priv v: &'self [T],
     priv size: uint
@@ -507,16 +510,49 @@ pub struct ChunkIter<'self, T> {
 
 impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
     fn next(&mut self) -> Option<&'self [T]> {
-        if self.size == 0 {
+        if self.v.len() == 0 {
             None
-        } else if self.size >= self.v.len() {
-            // finished
-            self.size = 0;
-            Some(self.v)
         } else {
-            let ret = Some(self.v.slice(0, self.size));
-            self.v = self.v.slice(self.size, self.v.len());
-            ret
+            let chunksz = cmp::min(self.v.len(), self.size);
+            let (fst, snd) = (self.v.slice_to(chunksz),
+                              self.v.slice_from(chunksz));
+            self.v = snd;
+            Some(fst)
+        }
+    }
+}
+
+impl<'self, T> DoubleEndedIterator<&'self [T]> for ChunkIter<'self, T> {
+    fn next_back(&mut self) -> Option<&'self [T]> {
+        if self.v.len() == 0 {
+            None
+        } else {
+            let remainder = self.v.len() % self.size;
+            let chunksz = if remainder != 0 { remainder } else { self.size };
+            let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
+                              self.v.slice_from(self.v.len() - chunksz));
+            self.v = fst;
+            Some(snd)
+        }
+    }
+}
+
+impl<'self, T> RandomAccessIterator<&'self [T]> for ChunkIter<'self, T> {
+    #[inline]
+    fn indexable(&self) -> uint {
+        self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
+    }
+
+    #[inline]
+    fn idx(&self, index: uint) -> Option<&'self [T]> {
+        if index < self.indexable() {
+            let lo = index * self.size;
+            let mut hi = lo + self.size;
+            if hi < lo || hi > self.v.len() { hi = self.v.len(); }
+
+            Some(self.v.slice(lo, hi))
+        } else {
+            None
         }
     }
 }
@@ -3380,6 +3416,14 @@ mod tests {
         assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
         assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
         assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
+
+        assert_eq!(v.chunk_iter(2).invert().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
+        let it = v.chunk_iter(2);
+        assert_eq!(it.indexable(), 3);
+        assert_eq!(it.idx(0).unwrap(), &[1,2]);
+        assert_eq!(it.idx(1).unwrap(), &[3,4]);
+        assert_eq!(it.idx(2).unwrap(), &[5]);
+        assert_eq!(it.idx(3), None);
     }
 
     #[test]