about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-14 00:01:04 -0700
committerbors <bors@rust-lang.org>2013-09-14 00:01:04 -0700
commit2aa578efd9834e37ad52879ff10ee2c2aa938389 (patch)
treeaa459cb42c65433dfbddca28040db544aea89f59 /src/libstd
parent4ac10f8f6e8e07c70fadb676170c5402442e2243 (diff)
parent93683ae6da3a47f1cd0644a093cb4b1b0bee7faa (diff)
downloadrust-2aa578efd9834e37ad52879ff10ee2c2aa938389.tar.gz
rust-2aa578efd9834e37ad52879ff10ee2c2aa938389.zip
auto merge of #9115 : erickt/rust/master, r=erickt
This is a series of patches to modernize option and result. The highlights are:

* rename `.unwrap_or_default(value)` and etc to `.unwrap_or(value)`
* add `.unwrap_or_default()` that uses the `Default` trait
* add `Default` implementations for vecs, HashMap, Option
* add  `Option.and(T) -> Option<T>`, `Option.and_then(&fn() -> Option<T>) -> Option<T>`, `Option.or(T) -> Option<T>`, and `Option.or_else(&fn() -> Option<T>) -> Option<T>`
* add `option::ToOption`, `option::IntoOption`, `option::AsOption`, `result::ToResult`, `result::IntoResult`, `result::AsResult`, `either::ToEither`, and `either::IntoEither`, `either::AsEither`
* renamed `Option::chain*` and `Result::chain*` to `and_then` and `or_else` to avoid the eventual collision with `Iterator.chain`.
* Added a bunch of impls of `Default`
* Added a `#[deriving(Default)]` syntax extension
* Removed impls of `Zero` for `Option<T>` and vecs. 
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs2
-rw-r--r--src/libstd/bool.rs7
-rw-r--r--src/libstd/char.rs10
-rw-r--r--src/libstd/default.rs12
-rw-r--r--src/libstd/either.rs196
-rw-r--r--src/libstd/hashmap.rs9
-rw-r--r--src/libstd/io.rs6
-rw-r--r--src/libstd/iter.rs9
-rw-r--r--src/libstd/num/f32.rs6
-rw-r--r--src/libstd/num/f64.rs6
-rw-r--r--src/libstd/num/float.rs6
-rw-r--r--src/libstd/num/int_macros.rs6
-rw-r--r--src/libstd/num/uint_macros.rs6
-rw-r--r--src/libstd/option.rs321
-rw-r--r--src/libstd/os.rs6
-rw-r--r--src/libstd/result.rs272
-rw-r--r--src/libstd/rt/io/net/ip.rs2
-rw-r--r--src/libstd/to_bytes.rs2
-rw-r--r--src/libstd/tuple.rs9
-rw-r--r--src/libstd/unit.rs11
-rw-r--r--src/libstd/vec.rs27
21 files changed, 833 insertions, 98 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index a4e841f98f8..ce8e90e1a43 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -45,7 +45,7 @@ pub fn capacity<T>(v: @[T]) -> uint {
 #[inline]
 pub fn build<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
     let mut vec = @[];
-    unsafe { raw::reserve(&mut vec, size.unwrap_or_default(4)); }
+    unsafe { raw::reserve(&mut vec, size.unwrap_or(4)); }
     builder(|x| unsafe { raw::push(&mut vec, x) });
     vec
 }
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index 926e6e1f6b6..4ef50094139 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -24,6 +24,7 @@ Implementations of the following traits:
 * `Ord`
 * `TotalOrd`
 * `Eq`
+* `Default`
 * `Zero`
 
 ## Various functions to compare `bool`s
@@ -43,6 +44,7 @@ use to_str::ToStr;
 
 #[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering};
 #[cfg(not(test))] use ops::Not;
+#[cfg(not(test))] use default::Default;
 #[cfg(not(test))] use num::Zero;
 
 /**
@@ -324,6 +326,11 @@ impl Eq for bool {
 }
 
 #[cfg(not(test))]
+impl Default for bool {
+    fn default() -> bool { false }
+}
+
+#[cfg(not(test))]
 impl Zero for bool {
     fn zero() -> bool { false }
     fn is_zero(&self) -> bool { *self == false }
diff --git a/src/libstd/char.rs b/src/libstd/char.rs
index 7f043b2ecaa..3a01e5908d9 100644
--- a/src/libstd/char.rs
+++ b/src/libstd/char.rs
@@ -21,6 +21,7 @@ use str;
 #[cfg(test)] use str::OwnedStr;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
+#[cfg(not(test))] use default::Default;
 #[cfg(not(test))] use num::Zero;
 
 // UTF-8 ranges and tags for encoding characters
@@ -435,8 +436,17 @@ impl Ord for char {
 }
 
 #[cfg(not(test))]
+impl Default for char {
+    #[inline]
+    fn default() -> char { '\x00' }
+}
+
+#[cfg(not(test))]
 impl Zero for char {
+    #[inline]
     fn zero() -> char { '\x00' }
+
+    #[inline]
     fn is_zero(&self) -> bool { *self == '\x00' }
 }
 
diff --git a/src/libstd/default.rs b/src/libstd/default.rs
index fbc60ffd01b..120cf3fa801 100644
--- a/src/libstd/default.rs
+++ b/src/libstd/default.rs
@@ -15,3 +15,15 @@ pub trait Default {
     /// Return the "default value" for a type.
     fn default() -> Self;
 }
+
+impl<T: Default + 'static> Default for @mut T {
+    fn default() -> @mut T { @mut Default::default() }
+}
+
+impl<T: Default + 'static> Default for @T {
+    fn default() -> @T { @Default::default() }
+}
+
+impl<T: Default> Default for ~T {
+    fn default() -> ~T { ~Default::default() }
+}
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index ec9e6d1ca4b..27381f64ad4 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -13,6 +13,7 @@
 #[allow(missing_doc)];
 
 use option::{Some, None};
+use option;
 use clone::Clone;
 use container::Container;
 use cmp::Eq;
@@ -53,18 +54,6 @@ impl<L, R> Either<L, R> {
         }
     }
 
-    /// 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 {
@@ -116,6 +105,101 @@ impl<L, R> Either<L, R> {
     }
 }
 
+/// A generic trait for converting a value to a `Either`
+pub trait ToEither<L, R> {
+    /// Convert to the `either` type
+    fn to_either(&self) -> Either<L, R>;
+}
+
+/// A generic trait for converting a value to a `Either`
+pub trait IntoEither<L, R> {
+    /// Convert to the `either` type
+    fn into_either(self) -> Either<L, R>;
+}
+
+/// A generic trait for converting a value to a `Either`
+pub trait AsEither<L, R> {
+    /// Convert to the `either` type
+    fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
+}
+
+impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
+    #[inline]
+    fn to_option(&self)-> option::Option<R> {
+        match *self {
+            Left(_) => None,
+            Right(ref r) => Some(r.clone()),
+        }
+    }
+}
+
+impl<L, R> option::IntoOption<R> for Either<L, R> {
+    #[inline]
+    fn into_option(self)-> option::Option<R> {
+        match self {
+            Left(_) => None,
+            Right(r) => Some(r),
+        }
+    }
+}
+
+impl<L, R> option::AsOption<R> for Either<L, R> {
+    #[inline]
+    fn as_option<'a>(&'a self) -> option::Option<&'a R> {
+        match *self {
+            Left(_) => None,
+            Right(ref r) => Some(r),
+        }
+    }
+}
+
+impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
+    #[inline]
+    fn to_result(&self)-> result::Result<R, L> {
+        match *self {
+            Left(ref l) => result::Err(l.clone()),
+            Right(ref r) => result::Ok(r.clone()),
+        }
+    }
+}
+
+impl<L, R> result::IntoResult<R, L> for Either<L, R> {
+    #[inline]
+    fn into_result(self)-> result::Result<R, L> {
+        match self {
+            Left(l) => result::Err(l),
+            Right(r) => result::Ok(r),
+        }
+    }
+}
+
+impl<L, R> result::AsResult<R, L> for Either<L, R> {
+    #[inline]
+    fn as_result<'a>(&'a self) -> result::Result<&'a R, &'a L> {
+        match *self {
+            Left(ref l) => result::Err(l),
+            Right(ref r) => result::Ok(r),
+        }
+    }
+}
+
+impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
+    fn to_either(&self) -> Either<L, R> { self.clone() }
+}
+
+impl<L, R> IntoEither<L, R> for Either<L, R> {
+    fn into_either(self) -> Either<L, R> { self }
+}
+
+impl<L, R> AsEither<L, R> for Either<L, R> {
+    fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
+        match *self {
+            Left(ref l) => Left(l),
+            Right(ref r) => Right(r),
+        }
+    }
+}
+
 /// An iterator yielding the `Left` values of its source
 pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
 
@@ -167,6 +251,11 @@ pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
 mod tests {
     use super::*;
 
+    use option::{IntoOption, ToOption, AsOption};
+    use option;
+    use result::{IntoResult, ToResult, AsResult};
+    use result;
+
     #[test]
     fn test_either_left() {
         let val = Left(10);
@@ -260,4 +349,87 @@ mod tests {
         assert_eq!(rights.len(), 0u);
     }
 
+    #[test]
+    pub fn test_to_option() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.to_option(), option::Some(100));
+        assert_eq!(left.to_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_into_option() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.into_option(), option::Some(100));
+        assert_eq!(left.into_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_as_option() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.as_option().unwrap(), &100);
+        assert_eq!(left.as_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_to_result() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.to_result(), result::Ok(100));
+        assert_eq!(left.to_result(), result::Err(404));
+    }
+
+    #[test]
+    pub fn test_into_result() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.into_result(), result::Ok(100));
+        assert_eq!(left.into_result(), result::Err(404));
+    }
+
+    #[test]
+    pub fn test_as_result() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        let x = 100;
+        assert_eq!(right.as_result(), result::Ok(&x));
+
+        let x = 404;
+        assert_eq!(left.as_result(), result::Err(&x));
+    }
+
+    #[test]
+    pub fn test_to_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.to_either(), Right(100));
+        assert_eq!(left.to_either(), Left(404));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.into_either(), Right(100));
+        assert_eq!(left.into_either(), Left(404));
+    }
+
+    #[test]
+    pub fn test_as_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.as_either().unwrap_right(), &100);
+        assert_eq!(left.as_either().unwrap_left(), &404);
+    }
 }
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 09f0af00417..6c0a6a4ea0a 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -18,6 +18,7 @@
 use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
 use clone::Clone;
 use cmp::{Eq, Equiv};
+use default::Default;
 use hash::Hash;
 use iter::{Iterator, FromIterator, Extendable};
 use iter::{FilterMap, Chain, Repeat, Zip};
@@ -622,6 +623,10 @@ impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
     }
 }
 
+impl<K: Eq + Hash, V> Default for HashMap<K, V> {
+    fn default() -> HashMap<K, V> { HashMap::new() }
+}
+
 /// An implementation of a hash set using the underlying representation of a
 /// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
 /// requires that the elements implement the `Eq` and `Hash` traits.
@@ -781,6 +786,10 @@ impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
     }
 }
 
+impl<K: Eq + Hash> Default for HashSet<K> {
+    fn default() -> HashSet<K> { HashSet::new() }
+}
+
 // `Repeat` is used to feed the filter closure an explicit capture
 // of a reference to the other set
 /// Set operations iterator
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index e9b704c2686..2ca36de4f49 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1618,7 +1618,7 @@ impl<T:Writer> WriterUtil for T {
 }
 
 pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
-    mk_file_writer(path, flags).chain(|w| Ok(w))
+    mk_file_writer(path, flags).and_then(|w| Ok(w))
 }
 
 
@@ -1779,7 +1779,7 @@ pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
 }
 
 pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
-    do read_whole_file(file).chain |bytes| {
+    do read_whole_file(file).and_then |bytes| {
         if str::is_utf8(bytes) {
             Ok(str::from_utf8(bytes))
         } else {
@@ -1791,7 +1791,7 @@ pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
 // FIXME (#2004): implement this in a low-level way. Going through the
 // abstractions is pointless.
 pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
-    do file_reader(file).chain |rdr| {
+    do file_reader(file).and_then |rdr| {
         Ok(rdr.read_whole_stream())
     }
 }
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 5ca827350d0..ec3c02a31f2 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -1474,7 +1474,7 @@ pub struct Scan<'self, A, B, T, St> {
 impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'self, A, B, T, St> {
     #[inline]
     fn next(&mut self) -> Option<B> {
-        self.iter.next().chain(|a| (self.f)(&mut self.state, a))
+        self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
     }
 
     #[inline]
@@ -1494,8 +1494,7 @@ pub struct FlatMap<'self, A, T, U> {
     priv backiter: Option<U>,
 }
 
-impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
-    FlatMap<'self, A, T, U> {
+impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'self, A, T, U> {
     #[inline]
     fn next(&mut self) -> Option<B> {
         loop {
@@ -1505,7 +1504,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
                 }
             }
             match self.iter.next().map_move(|x| (self.f)(x)) {
-                None => return self.backiter.chain_mut_ref(|it| it.next()),
+                None => return self.backiter.and_then_mut_ref(|it| it.next()),
                 next => self.frontiter = next,
             }
         }
@@ -1537,7 +1536,7 @@ impl<'self,
                 }
             }
             match self.iter.next_back().map_move(|x| (self.f)(x)) {
-                None => return self.frontiter.chain_mut_ref(|it| it.next_back()),
+                None => return self.frontiter.and_then_mut_ref(|it| it.next_back()),
                 next => self.backiter = next,
             }
         }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 899d6236aaa..0addcce3eb6 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -12,6 +12,7 @@
 #[allow(missing_doc)];
 #[allow(non_uppercase_statics)];
 
+use default::Default;
 use libc::c_int;
 use num::{Zero, One, strconv};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
@@ -237,6 +238,11 @@ impl Orderable for f32 {
     }
 }
 
+impl Default for f32 {
+    #[inline]
+    fn default() -> f32 { 0.0 }
+}
+
 impl Zero for f32 {
     #[inline]
     fn zero() -> f32 { 0.0 }
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 6ab8350a115..b0675278238 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -13,6 +13,7 @@
 #[allow(missing_doc)];
 #[allow(non_uppercase_statics)];
 
+use default::Default;
 use libc::c_int;
 use num::{Zero, One, strconv};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
@@ -260,6 +261,11 @@ impl Orderable for f64 {
     }
 }
 
+impl Default for f64 {
+    #[inline]
+    fn default() -> f64 { 0.0 }
+}
+
 impl Zero for f64 {
     #[inline]
     fn zero() -> f64 { 0.0 }
diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs
index df26fadae16..3952f5478f7 100644
--- a/src/libstd/num/float.rs
+++ b/src/libstd/num/float.rs
@@ -23,6 +23,7 @@
 #[allow(missing_doc)];
 #[allow(non_uppercase_statics)];
 
+use default::Default;
 use num::{Zero, One, strconv};
 use num::FPCategory;
 use num;
@@ -382,6 +383,11 @@ impl Orderable for float {
     }
 }
 
+impl Default for float {
+    #[inline]
+    fn default() -> float { 0.0 }
+}
+
 impl Zero for float {
     #[inline]
     fn zero() -> float { 0.0 }
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 07cafb0a4f1..ae2a56b835d 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -16,6 +16,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
 
 #[allow(non_uppercase_statics)];
 
+use default::Default;
 use num::{ToStrRadix, FromStrRadix};
 use num::{CheckedDiv, Zero, One, strconv};
 use prelude::*;
@@ -167,6 +168,11 @@ impl Orderable for $T {
     }
 }
 
+impl Default for $T {
+    #[inline]
+    fn default() -> $T { 0 }
+}
+
 impl Zero for $T {
     #[inline]
     fn zero() -> $T { 0 }
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index effeb60fc22..3deb7312b04 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -16,6 +16,7 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
 
 #[allow(non_uppercase_statics)];
 
+use default::Default;
 use num::BitCount;
 use num::{ToStrRadix, FromStrRadix};
 use num::{CheckedDiv, Zero, One, strconv};
@@ -172,6 +173,11 @@ impl Orderable for $T {
     }
 }
 
+impl Default for $T {
+    #[inline]
+    fn default() -> $T { 0 }
+}
+
 impl Zero for $T {
     #[inline]
     fn zero() -> $T { 0 }
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index b72046cce72..ce725257dff 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -43,10 +43,13 @@ let unwrapped_msg = match msg {
 
 use clone::Clone;
 use cmp::{Eq,Ord};
+use default::Default;
+use either;
 use util;
 use num::Zero;
 use iter;
 use iter::{Iterator, DoubleEndedIterator, ExactSize};
+use result;
 use str::{StrSlice, OwnedStr};
 use to_str::ToStr;
 use clone::DeepClone;
@@ -126,45 +129,64 @@ impl<T> Option<T> {
     #[inline]
     pub fn is_some(&self) -> bool { !self.is_none() }
 
-    /// Update an optional value by optionally running its content through a
-    /// function that returns an option.
+    /// Returns `None` if the option is `None`, otherwise returns `optb`.
     #[inline]
-    pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
+    pub fn and(self, optb: Option<T>) -> Option<T> {
         match self {
-            Some(t) => f(t),
-            None => None
+            Some(_) => optb,
+            None => None,
         }
     }
 
-    /// Returns the leftmost Some() value, or None if both are None.
+    /// Returns `None` if the option is `None`, otherwise calls `f` with the
+    /// wrapped value and returns the result.
     #[inline]
-    pub fn or(self, optb: Option<T>) -> Option<T> {
+    pub fn and_then<U>(self, f: &fn(T) -> Option<U>) -> Option<U> {
         match self {
-            Some(opta) => Some(opta),
-            _ => optb
+            Some(x) => f(x),
+            None => None,
         }
     }
 
-    /// Update an optional value by optionally running its content by reference
-    /// through a function that returns an option.
+    /// Returns `None` if the option is `None`, otherwise calls `f` with a
+    /// reference to the wrapped value and returns the result.
     #[inline]
-    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
+    pub fn and_then_ref<'a, U>(&'a self, f: &fn(&'a T) -> Option<U>) -> Option<U> {
         match *self {
             Some(ref x) => f(x),
             None => None
         }
     }
 
-    /// Update an optional value by optionally running its content by mut reference
-    /// through a function that returns an option.
+    /// Returns `None` if the option is `None`, otherwise calls `f` with a
+    /// mutable reference to the wrapped value and returns the result.
     #[inline]
-    pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>) -> Option<U> {
+    pub fn and_then_mut_ref<'a, U>(&'a mut self, f: &fn(&'a mut T) -> Option<U>) -> Option<U> {
         match *self {
             Some(ref mut x) => f(x),
             None => None
         }
     }
 
+    /// Returns the option if it contains a value, otherwise returns `optb`.
+    #[inline]
+    pub fn or(self, optb: Option<T>) -> Option<T> {
+        match self {
+            Some(_) => self,
+            None => optb
+        }
+    }
+
+    /// Returns the option if it contains a value, otherwise calls `f` and
+    /// returns the result.
+    #[inline]
+    pub fn or_else(self, f: &fn() -> Option<T>) -> Option<T> {
+        match self {
+            Some(_) => self,
+            None => f(),
+        }
+    }
+
     /// Filters an optional value using given function.
     #[inline(always)]
     pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option<T> {
@@ -332,13 +354,22 @@ impl<T> Option<T> {
 
     /// Returns the contained value or a default
     #[inline]
-    pub fn unwrap_or_default(self, def: T) -> T {
+    pub fn unwrap_or(self, def: T) -> T {
         match self {
             Some(x) => x,
             None => def
         }
     }
 
+    /// Returns the contained value or computes it from a closure
+    #[inline]
+    pub fn unwrap_or_else(self, f: &fn() -> T) -> T {
+        match self {
+            Some(x) => x,
+            None => f()
+        }
+    }
+
     /// Applies a function zero or more times until the result is `None`.
     #[inline]
     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
@@ -349,6 +380,109 @@ impl<T> Option<T> {
     }
 }
 
+/// A generic trait for converting a value to a `Option`
+pub trait ToOption<T> {
+    /// Convert to the `option` type
+    fn to_option(&self) -> Option<T>;
+}
+
+/// A generic trait for converting a value to a `Option`
+pub trait IntoOption<T> {
+    /// Convert to the `option` type
+    fn into_option(self) -> Option<T>;
+}
+
+/// A generic trait for converting a value to a `Option`
+pub trait AsOption<T> {
+    /// Convert to the `option` type
+    fn as_option<'a>(&'a self) -> Option<&'a T>;
+}
+
+impl<T: Clone> ToOption<T> for Option<T> {
+    #[inline]
+    fn to_option(&self) -> Option<T> { self.clone() }
+}
+
+impl<T> IntoOption<T> for Option<T> {
+    #[inline]
+    fn into_option(self) -> Option<T> { self }
+}
+
+impl<T> AsOption<T> for Option<T> {
+    #[inline]
+    fn as_option<'a>(&'a self) -> Option<&'a T> {
+        match *self {
+            Some(ref x) => Some(x),
+            None => None,
+        }
+    }
+}
+
+impl<T: Clone> result::ToResult<T, ()> for Option<T> {
+    #[inline]
+    fn to_result(&self) -> result::Result<T, ()> {
+        match *self {
+            Some(ref x) => result::Ok(x.clone()),
+            None => result::Err(()),
+        }
+    }
+}
+
+impl<T> result::IntoResult<T, ()> for Option<T> {
+    #[inline]
+    fn into_result(self) -> result::Result<T, ()> {
+        match self {
+            Some(x) => result::Ok(x),
+            None => result::Err(()),
+        }
+    }
+}
+
+impl<T: Clone> either::ToEither<(), T> for Option<T> {
+    #[inline]
+    fn to_either(&self) -> either::Either<(), T> {
+        match *self {
+            Some(ref x) => either::Right(x.clone()),
+            None => either::Left(()),
+        }
+    }
+}
+
+impl<T> either::IntoEither<(), T> for Option<T> {
+    #[inline]
+    fn into_either(self) -> either::Either<(), T> {
+        match self {
+            Some(x) => either::Right(x),
+            None => either::Left(()),
+        }
+    }
+}
+
+impl<T: Default> Option<T> {
+    /// Returns the contained value or default (for this type)
+    #[inline]
+    pub fn unwrap_or_default(self) -> T {
+        match self {
+            Some(x) => x,
+            None => Default::default()
+        }
+    }
+
+    /// Returns self or `Some`-wrapped default value
+    #[inline]
+    pub fn or_default(self) -> Option<T> {
+        match self {
+            None => Some(Default::default()),
+            x => x,
+        }
+    }
+}
+
+impl<T> Default for Option<T> {
+    #[inline]
+    fn default() -> Option<T> { None }
+}
+
 impl<T:Zero> Option<T> {
     /// Returns the contained value or zero (for this type)
     #[inline]
@@ -369,11 +503,6 @@ impl<T:Zero> Option<T> {
     }
 }
 
-impl<T> Zero for Option<T> {
-    fn zero() -> Option<T> { None }
-    fn is_zero(&self) -> bool { self.is_none() }
-}
-
 /// An iterator that yields either one or zero elements
 #[deriving(Clone, DeepClone)]
 pub struct OptionIterator<A> {
@@ -407,6 +536,11 @@ impl<A> ExactSize<A> for OptionIterator<A> {}
 #[cfg(test)]
 mod tests {
     use super::*;
+
+    use either::{IntoEither, ToEither};
+    use either;
+    use result::{IntoResult, ToResult};
+    use result;
     use util;
 
     #[test]
@@ -476,6 +610,50 @@ mod tests {
     }
 
     #[test]
+    fn test_and() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.and(Some(2)), Some(2));
+        assert_eq!(x.and(None), None);
+
+        let x: Option<int> = None;
+        assert_eq!(x.and(Some(2)), None);
+        assert_eq!(x.and(None), None);
+    }
+
+    #[test]
+    fn test_and_then() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
+        assert_eq!(x.and_then(|_| None::<int>), None);
+
+        let x: Option<int> = None;
+        assert_eq!(x.and_then(|x| Some(x + 1)), None);
+        assert_eq!(x.and_then(|_| None::<int>), None);
+    }
+
+    #[test]
+    fn test_or() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.or(Some(2)), Some(1));
+        assert_eq!(x.or(None), Some(1));
+
+        let x: Option<int> = None;
+        assert_eq!(x.or(Some(2)), Some(2));
+        assert_eq!(x.or(None), None);
+    }
+
+    #[test]
+    fn test_or_else() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.or_else(|| Some(2)), Some(1));
+        assert_eq!(x.or_else(|| None), Some(1));
+
+        let x: Option<int> = None;
+        assert_eq!(x.or_else(|| Some(2)), Some(2));
+        assert_eq!(x.or_else(|| None), None);
+    }
+
+    #[test]
     fn test_option_while_some() {
         let mut i = 0;
         do Some(10).while_some |j| {
@@ -490,6 +668,44 @@ mod tests {
     }
 
     #[test]
+    fn test_unwrap() {
+        assert_eq!(Some(1).unwrap(), 1);
+        assert_eq!(Some(~"hello").unwrap(), ~"hello");
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_unwrap_fail1() {
+        let x: Option<int> = None;
+        x.unwrap();
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_unwrap_fail2() {
+        let x: Option<~str> = None;
+        x.unwrap();
+    }
+
+    #[test]
+    fn test_unwrap_or() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.unwrap_or(2), 1);
+
+        let x: Option<int> = None;
+        assert_eq!(x.unwrap_or(2), 2);
+    }
+
+    #[test]
+    fn test_unwrap_or_else() {
+        let x: Option<int> = Some(1);
+        assert_eq!(x.unwrap_or_else(|| 2), 1);
+
+        let x: Option<int> = None;
+        assert_eq!(x.unwrap_or_else(|| 2), 2);
+    }
+
+    #[test]
     fn test_unwrap_or_zero() {
         let some_stuff = Some(42);
         assert_eq!(some_stuff.unwrap_or_zero(), 42);
@@ -566,4 +782,67 @@ mod tests {
         assert!(!x.mutate_default(0i, |i| i+1));
         assert_eq!(x, Some(0i));
     }
+
+    #[test]
+    pub fn test_to_option() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.to_option(), Some(100));
+        assert_eq!(none.to_option(), None);
+    }
+
+    #[test]
+    pub fn test_into_option() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.into_option(), Some(100));
+        assert_eq!(none.into_option(), None);
+    }
+
+    #[test]
+    pub fn test_as_option() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.as_option().unwrap(), &100);
+        assert_eq!(none.as_option(), None);
+    }
+
+    #[test]
+    pub fn test_to_result() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.to_result(), result::Ok(100));
+        assert_eq!(none.to_result(), result::Err(()));
+    }
+
+    #[test]
+    pub fn test_into_result() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.into_result(), result::Ok(100));
+        assert_eq!(none.into_result(), result::Err(()));
+    }
+
+    #[test]
+    pub fn test_to_either() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.to_either(), either::Right(100));
+        assert_eq!(none.to_either(), either::Left(()));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.into_either(), either::Right(100));
+        assert_eq!(none.into_either(), either::Left(()));
+    }
 }
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index ab1210aabad..aeeae207204 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -569,7 +569,7 @@ pub fn homedir() -> Option<Path> {
 
     #[cfg(windows)]
     fn secondary() -> Option<Path> {
-        do getenv("USERPROFILE").chain |p| {
+        do getenv("USERPROFILE").and_then |p| {
             if !p.is_empty() {
                 Some(Path(p))
             } else {
@@ -611,7 +611,7 @@ pub fn tmpdir() -> Path {
         if cfg!(target_os = "android") {
             Path("/data/tmp")
         } else {
-            getenv_nonempty("TMPDIR").unwrap_or_default(Path("/tmp"))
+            getenv_nonempty("TMPDIR").unwrap_or(Path("/tmp"))
         }
     }
 
@@ -620,7 +620,7 @@ pub fn tmpdir() -> Path {
         getenv_nonempty("TMP").or(
             getenv_nonempty("TEMP").or(
                 getenv_nonempty("USERPROFILE").or(
-                   getenv_nonempty("WINDIR")))).unwrap_or_default(Path("C:\\Windows"))
+                   getenv_nonempty("WINDIR")))).unwrap_or(Path("C:\\Windows"))
     }
 }
 
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 793086dca78..3811f34cec4 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -17,6 +17,7 @@ use cmp::Eq;
 use either;
 use iter::Iterator;
 use option::{None, Option, Some, OptionIterator};
+use option;
 use vec;
 use vec::OwnedVector;
 use to_str::ToStr;
@@ -36,18 +37,6 @@ pub enum Result<T, E> {
 }
 
 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 {
-            Ok(t) => either::Right(t),
-            Err(e) => either::Left(e),
-        }
-    }
-
     /// Get a reference to the value out of a successful result
     ///
     /// # Failure
@@ -184,8 +173,20 @@ impl<T, E: ToStr> Result<T, E> {
 
     /// Call a method based on a previous result
     ///
+    /// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`,
+    /// then `self` is returned.
+    #[inline]
+    pub fn and(self, res: Result<T, E>) -> Result<T, E> {
+        match self {
+            Ok(_) => res,
+            Err(_) => self,
+        }
+    }
+
+    /// 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
+    /// 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.
     ///
@@ -195,13 +196,25 @@ impl<T, E: ToStr> Result<T, E> {
     ///         Ok(parse_bytes(buf))
     ///     };
     #[inline]
-    pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
+    pub fn and_then<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
         match self {
             Ok(t) => op(t),
             Err(e) => Err(e),
         }
     }
 
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Ok`, then `self` is returned. If `self` is `Err`
+    /// then `res` is returned.
+    #[inline]
+    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
+        match self {
+            Ok(_) => self,
+            Err(_) => res,
+        }
+    }
+
     /// Call a function based on a previous result
     ///
     /// If `self` is `Err` then the value is extracted and passed to `op`
@@ -209,7 +222,7 @@ impl<T, E: ToStr> Result<T, E> {
     /// 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> {
+    pub fn or_else<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
         match self {
             Ok(t) => Ok(t),
             Err(e) => op(e),
@@ -255,6 +268,104 @@ impl<T, E: Clone + ToStr> Result<T, E> {
     }
 }
 
+/// A generic trait for converting a value to a `Result`
+pub trait ToResult<T, E> {
+    /// Convert to the `result` type
+    fn to_result(&self) -> Result<T, E>;
+}
+
+/// A generic trait for converting a value to a `Result`
+pub trait IntoResult<T, E> {
+    /// Convert to the `result` type
+    fn into_result(self) -> Result<T, E>;
+}
+
+/// A generic trait for converting a value to a `Result`
+pub trait AsResult<T, E> {
+    /// Convert to the `result` type
+    fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
+}
+
+impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
+    #[inline]
+    fn to_option(&self)-> Option<T> {
+        match *self {
+            Ok(ref t) => Some(t.clone()),
+            Err(_) => None,
+        }
+    }
+}
+
+impl<T, E> option::IntoOption<T> for Result<T, E> {
+    #[inline]
+    fn into_option(self)-> Option<T> {
+        match self {
+            Ok(t) => Some(t),
+            Err(_) => None,
+        }
+    }
+}
+
+impl<T, E> option::AsOption<T> for Result<T, E> {
+    #[inline]
+    fn as_option<'a>(&'a self)-> Option<&'a T> {
+        match *self {
+            Ok(ref t) => Some(t),
+            Err(_) => None,
+        }
+    }
+}
+
+impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
+    #[inline]
+    fn to_result(&self) -> Result<T, E> { self.clone() }
+}
+
+impl<T, E> IntoResult<T, E> for Result<T, E> {
+    #[inline]
+    fn into_result(self) -> Result<T, E> { self }
+}
+
+impl<T, E> AsResult<T, E> for Result<T, E> {
+    #[inline]
+    fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
+        match *self {
+            Ok(ref t) => Ok(t),
+            Err(ref e) => Err(e),
+        }
+    }
+}
+
+impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
+    #[inline]
+    fn to_either(&self)-> either::Either<E, T> {
+        match *self {
+            Ok(ref t) => either::Right(t.clone()),
+            Err(ref e) => either::Left(e.clone()),
+        }
+    }
+}
+
+impl<T, E> either::IntoEither<E, T> for Result<T, E> {
+    #[inline]
+    fn into_either(self)-> either::Either<E, T> {
+        match self {
+            Ok(t) => either::Right(t),
+            Err(e) => either::Left(e),
+        }
+    }
+}
+
+impl<T, E> either::AsEither<E, T> for Result<T, E> {
+    #[inline]
+    fn as_either<'a>(&'a self)-> either::Either<&'a E, &'a T> {
+        match *self {
+            Ok(ref t) => either::Right(t),
+            Err(ref e) => either::Left(e),
+        }
+    }
+}
+
 #[inline]
 #[allow(missing_doc)]
 pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
@@ -334,27 +445,51 @@ pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
 mod tests {
     use super::*;
 
+    use either::{IntoEither, ToEither, AsEither};
     use either;
     use iter::range;
+    use option::{IntoOption, ToOption, AsOption};
+    use option;
     use str::OwnedStr;
     use vec::ImmutableVector;
 
     pub fn op1() -> Result<int, ~str> { Ok(666) }
+    pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
+
+    #[test]
+    pub fn test_and() {
+        assert_eq!(op1().and(Ok(667)).unwrap(), 667);
+        assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad");
 
-    pub fn op2(i: int) -> Result<uint, ~str> {
-        Ok(i as uint + 1u)
+        assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
+        assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface");
     }
 
-    pub fn op3() -> Result<int, ~str> { Err(~"sadface") }
+    #[test]
+    pub fn test_and_then() {
+        assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
+        assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
+
+        assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
+        assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
+    }
 
     #[test]
-    pub fn chain_success() {
-        assert_eq!(op1().chain(op2).unwrap(), 667u);
+    pub fn test_or() {
+        assert_eq!(op1().or(Ok(667)).unwrap(), 666);
+        assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
+
+        assert_eq!(op2().or(Ok(667)).unwrap(), 667);
+        assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
     }
 
     #[test]
-    pub fn chain_failure() {
-        assert_eq!(op3().chain( op2).unwrap_err(), ~"sadface");
+    pub fn test_or_else() {
+        assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
+        assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
+
+        assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
+        assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
     }
 
     #[test]
@@ -413,15 +548,6 @@ mod tests {
     }
 
     #[test]
-    pub fn test_to_either() {
-        let r: Result<int, ()> = Ok(100);
-        let err: Result<(), int> = Err(404);
-
-        assert_eq!(r.to_either(), either::Right(100));
-        assert_eq!(err.to_either(), either::Left(404));
-    }
-
-    #[test]
     fn test_collect() {
         assert_eq!(collect(range(0, 0)
                            .map(|_| Ok::<int, ()>(0))),
@@ -460,4 +586,88 @@ mod tests {
                         .map(|f| (*f)())),
                    Err(1));
     }
+
+    #[test]
+    pub fn test_to_option() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.to_option(), option::Some(100));
+        assert_eq!(err.to_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_into_option() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.into_option(), option::Some(100));
+        assert_eq!(err.into_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_as_option() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.as_option().unwrap(), &100);
+        assert_eq!(err.as_option(), option::None);
+    }
+
+    #[test]
+    pub fn test_to_result() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.to_result(), Ok(100));
+        assert_eq!(err.to_result(), Err(404));
+    }
+
+    #[test]
+    pub fn test_into_result() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.into_result(), Ok(100));
+        assert_eq!(err.into_result(), Err(404));
+    }
+
+    #[test]
+    pub fn test_as_result() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        let x = 100;
+        assert_eq!(ok.as_result(), Ok(&x));
+
+        let x = 404;
+        assert_eq!(err.as_result(), Err(&x));
+    }
+
+    #[test]
+    pub fn test_to_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.to_either(), either::Right(100));
+        assert_eq!(err.to_either(), either::Left(404));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.into_either(), either::Right(100));
+        assert_eq!(err.into_either(), either::Left(404));
+    }
+
+    #[test]
+    pub fn test_as_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.as_either().unwrap_right(), &100);
+        assert_eq!(err.as_either().unwrap_left(), &404);
+    }
 }
diff --git a/src/libstd/rt/io/net/ip.rs b/src/libstd/rt/io/net/ip.rs
index 956dd08ac91..041253455f0 100644
--- a/src/libstd/rt/io/net/ip.rs
+++ b/src/libstd/rt/io/net/ip.rs
@@ -177,7 +177,7 @@ impl<'self> Parser<'self> {
         }
 
         do self.read_atomically |p| {
-            p.read_char().chain(|c| parse_digit(c, radix))
+            p.read_char().and_then(|c| parse_digit(c, radix))
         }
     }
 
diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs
index 855cdfcb851..f47468e1ef8 100644
--- a/src/libstd/to_bytes.rs
+++ b/src/libstd/to_bytes.rs
@@ -383,5 +383,5 @@ mod test {
     #[test] fn iterbytes_compiles () {
         takes_iterbytes((3,4,5,false));
     }
-    fn takes_iterbytes<T : IterBytes>(x : T) {}
+    fn takes_iterbytes<T : IterBytes>(_x : T) {}
 }
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 5d9ca6202e2..2591131f215 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -89,6 +89,7 @@ macro_rules! tuple_impls {
         pub mod inner {
             use clone::Clone;
             #[cfg(not(test))] use cmp::*;
+            #[cfg(not(test))] use default::Default;
             #[cfg(not(test))] use num::Zero;
 
             $(
@@ -173,6 +174,14 @@ macro_rules! tuple_impls {
                 }
 
                 #[cfg(not(test))]
+                impl<$($T:Default),+> Default for ($($T,)+) {
+                    #[inline]
+                    fn default() -> ($($T,)+) {
+                        ($({ let x: $T = Default::default(); x},)+)
+                    }
+                }
+
+                #[cfg(not(test))]
                 impl<$($T:Zero),+> Zero for ($($T,)+) {
                     #[inline]
                     fn zero() -> ($($T,)+) {
diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs
index 3af0322df56..dfe4abe54e5 100644
--- a/src/libstd/unit.rs
+++ b/src/libstd/unit.rs
@@ -46,14 +46,15 @@ impl TotalEq for () {
 }
 
 #[cfg(not(test))]
+impl Default for () {
+    #[inline]
+    fn default() -> () { () }
+}
+
+#[cfg(not(test))]
 impl Zero for () {
     #[inline]
     fn zero() -> () { () }
     #[inline]
     fn is_zero(&self) -> bool { true }
 }
-
-#[cfg(not(test))]
-impl Default for () {
-    fn default() -> () { () }
-}
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 1ff58351886..47c3a079614 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -104,9 +104,10 @@ use clone::{Clone, DeepClone};
 use container::{Container, Mutable};
 use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
 use cmp;
+use default::Default;
 use iter::*;
 use libc::c_void;
-use num::{Integer, Zero, CheckedAdd, Saturating};
+use num::{Integer, CheckedAdd, Saturating};
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
@@ -205,7 +206,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
  */
 #[inline]
 pub fn build<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> ~[A] {
-    let mut vec = with_capacity(size.unwrap_or_default(4));
+    let mut vec = with_capacity(size.unwrap_or(4));
     builder(|x| vec.push(x));
     vec
 }
@@ -2237,19 +2238,16 @@ impl<A: DeepClone> DeepClone for ~[A] {
 }
 
 // This works because every lifetime is a sub-lifetime of 'static
-impl<'self, A> Zero for &'self [A] {
-    fn zero() -> &'self [A] { &'self [] }
-    fn is_zero(&self) -> bool { self.is_empty() }
+impl<'self, A> Default for &'self [A] {
+    fn default() -> &'self [A] { &'self [] }
 }
 
-impl<A> Zero for ~[A] {
-    fn zero() -> ~[A] { ~[] }
-    fn is_zero(&self) -> bool { self.len() == 0 }
+impl<A> Default for ~[A] {
+    fn default() -> ~[A] { ~[] }
 }
 
-impl<A> Zero for @[A] {
-    fn zero() -> @[A] { @[] }
-    fn is_zero(&self) -> bool { self.len() == 0 }
+impl<A> Default for @[A] {
+    fn default() -> @[A] { @[] }
 }
 
 macro_rules! iterator {
@@ -3588,13 +3586,12 @@ mod tests {
     }
 
     #[test]
-    fn test_vec_zero() {
-        use num::Zero;
+    fn test_vec_default() {
+        use default::Default;
         macro_rules! t (
             ($ty:ty) => {{
-                let v: $ty = Zero::zero();
+                let v: $ty = Default::default();
                 assert!(v.is_empty());
-                assert!(v.is_zero());
             }}
         );