about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure1
-rw-r--r--doc/rustpkg.md5
-rw-r--r--mk/tests.mk10
-rw-r--r--src/libextra/dlist.rs64
-rw-r--r--src/libstd/iterator.rs157
-rw-r--r--src/libstd/macros.rs16
-rw-r--r--src/libstd/option.rs33
-rw-r--r--src/libstd/prelude.rs1
-rw-r--r--src/libstd/tuple.rs80
-rw-r--r--src/libstd/vec.rs46
10 files changed, 327 insertions, 86 deletions
diff --git a/configure b/configure
index 609a7c46e36..9129fc0e19e 100755
--- a/configure
+++ b/configure
@@ -371,6 +371,7 @@ opt docs     1 "build documentation"
 opt optimize 1 "build optimized rust code"
 opt optimize-cxx 1 "build optimized C++ code"
 opt optimize-llvm 1 "build optimized LLVM"
+opt optimize-tests 1 "build tests with optimizations"
 opt llvm-assertions 1 "build LLVM with assertions"
 opt debug 0 "build with extra debug fun"
 opt ratchet-bench 0 "ratchet benchmarks"
diff --git a/doc/rustpkg.md b/doc/rustpkg.md
index 46ab7afab43..1e6e4e29cb9 100644
--- a/doc/rustpkg.md
+++ b/doc/rustpkg.md
@@ -103,6 +103,11 @@ When building a package that is in a `git` repository,
 When building a package that is not under version control,
 or that has no tags, `rustpkg` assumes the intended version is 0.1.
 
+> **Note:** A future version of rustpkg will support semantic versions.
+> Also, a future version will add the option to specify a version with a metadata
+> attribute like `#[link(vers = "3.1415")]` inside the crate module,
+> though this attribute will never be mandatory.
+
 # Dependencies
 
 rustpkg infers dependencies from `extern mod` directives.
diff --git a/mk/tests.mk b/mk/tests.mk
index 349ffc63d97..e644248c370 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -552,7 +552,15 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
 
 # The tests select when to use debug configuration on their own;
 # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
-CTEST_RUSTC_FLAGS = $$(subst --cfg debug,,$$(CFG_RUSTC_FLAGS))
+CTEST_RUSTC_FLAGS := $$(subst --cfg debug,,$$(CFG_RUSTC_FLAGS))
+
+# The tests can not be optimized while the rest of the compiler is optimized, so
+# filter out the optimization (if any) from rustc and then figure out if we need
+# to be optimized
+CTEST_RUSTC_FLAGS := $$(subst -O,,$$(CTEST_RUSTC_FLAGS))
+ifndef CFG_DISABLE_OPTIMIZE_TESTS
+CTEST_RUSTC_FLAGS += -O
+endif
 
 CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=						\
 		--compile-lib-path $$(HLIB$(1)_H_$(3))				\
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 19a72b0029f..788ed726d0f 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -26,6 +26,7 @@ use std::cast;
 use std::ptr;
 use std::util;
 use std::iterator::{FromIterator, Extendable, Invert};
+use std::iterator;
 
 use container::Deque;
 
@@ -589,12 +590,27 @@ impl<A, T: Iterator<A>> Extendable<A, T> for DList<A> {
 impl<A: Eq> Eq for DList<A> {
     fn eq(&self, other: &DList<A>) -> bool {
         self.len() == other.len() &&
-            self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
+            iterator::order::eq(self.iter(), other.iter())
     }
 
-    #[inline]
     fn ne(&self, other: &DList<A>) -> bool {
-        !self.eq(other)
+        self.len() != other.len() &&
+            iterator::order::ne(self.iter(), other.iter())
+    }
+}
+
+impl<A: Eq + Ord> Ord for DList<A> {
+    fn lt(&self, other: &DList<A>) -> bool {
+        iterator::order::lt(self.iter(), other.iter())
+    }
+    fn le(&self, other: &DList<A>) -> bool {
+        iterator::order::le(self.iter(), other.iter())
+    }
+    fn gt(&self, other: &DList<A>) -> bool {
+        iterator::order::gt(self.iter(), other.iter())
+    }
+    fn ge(&self, other: &DList<A>) -> bool {
+        iterator::order::ge(self.iter(), other.iter())
     }
 }
 
@@ -965,6 +981,48 @@ mod tests {
     }
 
     #[test]
+    fn test_ord() {
+        let n: DList<int> = list_from([]);
+        let m = list_from([1,2,3]);
+        assert!(n < m);
+        assert!(m > n);
+        assert!(n <= n);
+        assert!(n >= n);
+    }
+
+    #[test]
+    fn test_ord_nan() {
+        let nan = 0.0/0.0;
+        let n = list_from([nan]);
+        let m = list_from([nan]);
+        assert!(!(n < m));
+        assert!(!(n > m));
+        assert!(!(n <= m));
+        assert!(!(n >= m));
+
+        let n = list_from([nan]);
+        let one = list_from([1.0]);
+        assert!(!(n < one));
+        assert!(!(n > one));
+        assert!(!(n <= one));
+        assert!(!(n >= one));
+
+        let u = list_from([1.0,2.0,nan]);
+        let v = list_from([1.0,2.0,3.0]);
+        assert!(!(u < v));
+        assert!(!(u > v));
+        assert!(!(u <= v));
+        assert!(!(u >= v));
+
+        let s = list_from([1.0,2.0,4.0,2.0]);
+        let t = list_from([1.0,2.0,3.0,2.0]);
+        assert!(!(s < t));
+        assert!(s > one);
+        assert!(!(s <= one));
+        assert!(s >= one);
+    }
+
+    #[test]
     fn test_fuzz() {
         do 25.times {
             fuzz_test(3);
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index e2d157c2a59..bd89c271a36 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -1568,6 +1568,163 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
     fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
 }
 
+/// Functions for lexicographical ordering of sequences.
+///
+/// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
+/// that the elements implement both `Eq` and `Ord`.
+///
+/// If two sequences are equal up until the point where one ends,
+/// the shorter sequence compares less.
+pub mod order {
+    use cmp;
+    use cmp::{TotalEq, TotalOrd, Ord, Eq};
+    use option::{Some, None};
+    use super::Iterator;
+
+    /// Compare `a` and `b` for equality using `TotalOrd`
+    pub fn equals<A: TotalEq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return true,
+                (None, _) | (_, None) => return false,
+                (Some(x), Some(y)) => if !x.equals(&y) { return false },
+            }
+        }
+    }
+
+    /// Order `a` and `b` lexicographically using `TotalOrd`
+    pub fn cmp<A: TotalOrd, T: Iterator<A>>(mut a: T, mut b: T) -> cmp::Ordering {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return cmp::Equal,
+                (None, _   ) => return cmp::Less,
+                (_   , None) => return cmp::Greater,
+                (Some(x), Some(y)) => match x.cmp(&y) {
+                    cmp::Equal => (),
+                    non_eq => return non_eq,
+                },
+            }
+        }
+    }
+
+    /// Compare `a` and `b` for equality (Using partial equality, `Eq`)
+    pub fn eq<A: Eq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return true,
+                (None, _) | (_, None) => return false,
+                (Some(x), Some(y)) => if !x.eq(&y) { return false },
+            }
+        }
+    }
+
+    /// Compare `a` and `b` for nonequality (Using partial equality, `Eq`)
+    pub fn ne<A: Eq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return false,
+                (None, _) | (_, None) => return true,
+                (Some(x), Some(y)) => if x.ne(&y) { return true },
+            }
+        }
+    }
+
+    /// Return `a` < `b` lexicographically (Using partial order, `Ord`)
+    pub fn lt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return false,
+                (None, _   ) => return true,
+                (_   , None) => return false,
+                (Some(x), Some(y)) => if x.ne(&y) { return x.lt(&y) },
+            }
+        }
+    }
+
+    /// Return `a` <= `b` lexicographically (Using partial order, `Ord`)
+    pub fn le<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return true,
+                (None, _   ) => return true,
+                (_   , None) => return false,
+                (Some(x), Some(y)) => if x.ne(&y) { return x.le(&y) },
+            }
+        }
+    }
+
+    /// Return `a` > `b` lexicographically (Using partial order, `Ord`)
+    pub fn gt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return false,
+                (None, _   ) => return false,
+                (_   , None) => return true,
+                (Some(x), Some(y)) => if x.ne(&y) { return x.gt(&y) },
+            }
+        }
+    }
+
+    /// Return `a` >= `b` lexicographically (Using partial order, `Ord`)
+    pub fn ge<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
+        loop {
+            match (a.next(), b.next()) {
+                (None, None) => return true,
+                (None, _   ) => return false,
+                (_   , None) => return true,
+                (Some(x), Some(y)) => if x.ne(&y) { return x.ge(&y) },
+            }
+        }
+    }
+
+    #[test]
+    fn test_lt() {
+        use vec::ImmutableVector;
+
+        let empty: [int, ..0] = [];
+        let xs = [1,2,3];
+        let ys = [1,2,0];
+
+        assert!(!lt(xs.iter(), ys.iter()));
+        assert!(!le(xs.iter(), ys.iter()));
+        assert!( gt(xs.iter(), ys.iter()));
+        assert!( ge(xs.iter(), ys.iter()));
+
+        assert!( lt(ys.iter(), xs.iter()));
+        assert!( le(ys.iter(), xs.iter()));
+        assert!(!gt(ys.iter(), xs.iter()));
+        assert!(!ge(ys.iter(), xs.iter()));
+
+        assert!( lt(empty.iter(), xs.iter()));
+        assert!( le(empty.iter(), xs.iter()));
+        assert!(!gt(empty.iter(), xs.iter()));
+        assert!(!ge(empty.iter(), xs.iter()));
+
+        // Sequence with NaN
+        let u = [1.0, 2.0];
+        let v = [0.0/0.0, 3.0];
+
+        assert!(!lt(u.iter(), v.iter()));
+        assert!(!le(u.iter(), v.iter()));
+        assert!(!gt(u.iter(), v.iter()));
+        assert!(!ge(u.iter(), v.iter()));
+
+        let a = [0.0/0.0];
+        let b = [1.0];
+        let c = [2.0];
+
+        assert!(lt(a.iter(), b.iter()) == (a[0] <  b[0]));
+        assert!(le(a.iter(), b.iter()) == (a[0] <= b[0]));
+        assert!(gt(a.iter(), b.iter()) == (a[0] >  b[0]));
+        assert!(ge(a.iter(), b.iter()) == (a[0] >= b[0]));
+
+        assert!(lt(c.iter(), b.iter()) == (c[0] <  b[0]));
+        assert!(le(c.iter(), b.iter()) == (c[0] <= b[0]));
+        assert!(gt(c.iter(), b.iter()) == (c[0] >  b[0]));
+        assert!(ge(c.iter(), b.iter()) == (c[0] >= b[0]));
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 04058887970..89c7b294512 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -16,20 +16,12 @@ macro_rules! rterrln (
     } )
 )
 
-// Some basic logging
-macro_rules! rtdebug_ (
-    ($( $arg:expr),+) => ( {
-        rterrln!( $($arg),+ )
-    } )
-)
-
-// An alternate version with no output, for turning off logging. An
-// earlier attempt that did not call the fmt! macro was insufficient,
-// as a case of the "let bind each variable" approach eventually
-// failed without an error message describing the invocation site.
+// Some basic logging. Enabled by passing `--cfg rtdebug` to the libstd build.
 macro_rules! rtdebug (
     ($( $arg:expr),+) => ( {
-        let _x = fmt!( $($arg),+ );
+        if cfg!(rtdebug) {
+            rterrln!( $($arg),+ )
+        }
     })
 )
 
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index c1999ae47d6..04e839cf691 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -47,6 +47,7 @@ use ops::Add;
 use util;
 use num::Zero;
 use iterator::Iterator;
+use iterator;
 use str::{StrSlice, OwnedStr};
 use to_str::ToStr;
 use clone::DeepClone;
@@ -58,31 +59,21 @@ pub enum Option<T> {
     Some(T),
 }
 
-impl<T:Ord> Ord for Option<T> {
+impl<T: Eq + Ord> Ord for Option<T> {
     fn lt(&self, other: &Option<T>) -> bool {
-        match (self, other) {
-            (&None, &None) => false,
-            (&None, &Some(_)) => true,
-            (&Some(_), &None) => false,
-            (&Some(ref a), &Some(ref b)) => *a < *b
-        }
+        iterator::order::lt(self.iter(), other.iter())
     }
 
     fn le(&self, other: &Option<T>) -> bool {
-        match (self, other) {
-            (&None, &None) => true,
-            (&None, &Some(_)) => true,
-            (&Some(_), &None) => false,
-            (&Some(ref a), &Some(ref b)) => *a <= *b
-        }
+        iterator::order::le(self.iter(), other.iter())
     }
 
     fn ge(&self, other: &Option<T>) -> bool {
-        !(self < other)
+        iterator::order::ge(self.iter(), other.iter())
     }
 
     fn gt(&self, other: &Option<T>) -> bool {
-        !(self <= other)
+        iterator::order::gt(self.iter(), other.iter())
     }
 }
 
@@ -554,6 +545,18 @@ mod tests {
     }
 
     #[test]
+    fn test_ord() {
+        let small = Some(1.0);
+        let big = Some(5.0);
+        let nan = Some(0.0/0.0);
+        assert!(!(nan < big));
+        assert!(!(nan > big));
+        assert!(small < big);
+        assert!(None < big);
+        assert!(big > None);
+    }
+
+    #[test]
     fn test_mutate() {
         let mut x = Some(3i);
         assert!(x.mutate(|i| i+1));
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 93e14be582b..deee49bc472 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -70,6 +70,7 @@ pub use from_str::FromStr;
 pub use to_bytes::IterBytes;
 pub use to_str::{ToStr, ToStrConsume};
 pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
+pub use tuple::{CloneableTuple1, ImmutableTuple1};
 pub use tuple::{CloneableTuple2, CloneableTuple3, CloneableTuple4, CloneableTuple5};
 pub use tuple::{CloneableTuple6, CloneableTuple7, CloneableTuple8, CloneableTuple9};
 pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12};
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 80d1626c084..8a3c024ede5 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -148,7 +148,7 @@ macro_rules! tuple_impls {
                     $(fn $get_fn(&self) -> $T;)+
                 }
 
-                impl<$($T:Clone),+> $cloneable_trait<$($T),+> for ($($T),+) {
+                impl<$($T:Clone),+> $cloneable_trait<$($T),+> for ($($T,)+) {
                     $(
                         #[inline]
                         fn $get_fn(&self) -> $T {
@@ -161,7 +161,7 @@ macro_rules! tuple_impls {
                     $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+
                 }
 
-                impl<$($T),+> $immutable_trait<$($T),+> for ($($T),+) {
+                impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) {
                     $(
                         #[inline]
                         fn $get_ref_fn<'a>(&'a self) -> &'a $T {
@@ -170,59 +170,65 @@ macro_rules! tuple_impls {
                     )+
                 }
 
-                impl<$($T:Clone),+> Clone for ($($T),+) {
-                    fn clone(&self) -> ($($T),+) {
-                        ($(self.$get_ref_fn().clone()),+)
+                impl<$($T:Clone),+> Clone for ($($T,)+) {
+                    fn clone(&self) -> ($($T,)+) {
+                        ($(self.$get_ref_fn().clone(),)+)
                     }
                 }
 
                 #[cfg(not(test))]
-                impl<$($T:Eq),+> Eq for ($($T),+) {
+                impl<$($T:Eq),+> Eq for ($($T,)+) {
                     #[inline]
-                    fn eq(&self, other: &($($T),+)) -> bool {
+                    fn eq(&self, other: &($($T,)+)) -> bool {
                         $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
                     }
                     #[inline]
-                    fn ne(&self, other: &($($T),+)) -> bool {
-                        !(*self == *other)
+                    fn ne(&self, other: &($($T,)+)) -> bool {
+                        $(*self.$get_ref_fn() != *other.$get_ref_fn())||+
                     }
                 }
 
                 #[cfg(not(test))]
-                impl<$($T:TotalEq),+> TotalEq for ($($T),+) {
+                impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {
                     #[inline]
-                    fn equals(&self, other: &($($T),+)) -> bool {
+                    fn equals(&self, other: &($($T,)+)) -> bool {
                         $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+
                     }
                 }
 
                 #[cfg(not(test))]
-                impl<$($T:Ord),+> Ord for ($($T),+) {
+                impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
                     #[inline]
-                    fn lt(&self, other: &($($T),+)) -> bool {
-                        lexical_lt!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                    fn lt(&self, other: &($($T,)+)) -> bool {
+                        lexical_ord!(lt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
                     }
                     #[inline]
-                    fn le(&self, other: &($($T),+)) -> bool { !(*other).lt(&(*self)) }
+                    fn le(&self, other: &($($T,)+)) -> bool {
+                        lexical_ord!(le, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                    }
                     #[inline]
-                    fn ge(&self, other: &($($T),+)) -> bool { !(*self).lt(other) }
+                    fn ge(&self, other: &($($T,)+)) -> bool {
+                        lexical_ord!(ge, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                    }
                     #[inline]
-                    fn gt(&self, other: &($($T),+)) -> bool { (*other).lt(&(*self)) }
+                    fn gt(&self, other: &($($T,)+)) -> bool {
+                        lexical_ord!(gt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                    }
                 }
 
                 #[cfg(not(test))]
-                impl<$($T:TotalOrd),+> TotalOrd for ($($T),+) {
+                impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) {
                     #[inline]
-                    fn cmp(&self, other: &($($T),+)) -> Ordering {
+                    fn cmp(&self, other: &($($T,)+)) -> Ordering {
                         lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
                     }
                 }
 
                 #[cfg(not(test))]
-                impl<$($T:Zero),+> Zero for ($($T),+) {
+                impl<$($T:Zero),+> Zero for ($($T,)+) {
                     #[inline]
-                    fn zero() -> ($($T),+) {
-                        ($(Zero::zero::<$T>()),+)
+                    fn zero() -> ($($T,)+) {
+                        ($(Zero::zero::<$T>(),)+)
                     }
                     #[inline]
                     fn is_zero(&self) -> bool {
@@ -234,17 +240,16 @@ macro_rules! tuple_impls {
     }
 }
 
-// Constructs an expression that performs a lexical less-than
-// ordering.  The values are interleaved, so the macro invocation for
-// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_lt!(a1, b1, a2, b2,
+// Constructs an expression that performs a lexical ordering using method $rel.
+// The values are interleaved, so the macro invocation for
+// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
 // a3, b3)` (and similarly for `lexical_cmp`)
-macro_rules! lexical_lt {
-    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
-        if *$a < *$b { true }
-        else if !(*$b < *$a) { lexical_lt!($($rest_a, $rest_b),+) }
-        else { false }
+macro_rules! lexical_ord {
+    ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
+        if *$a != *$b { lexical_ord!($rel, $a, $b) }
+        else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
     };
-    ($a:expr, $b:expr) => { *$a < *$b };
+    ($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($b) };
 }
 
 macro_rules! lexical_cmp {
@@ -259,6 +264,10 @@ macro_rules! lexical_cmp {
 
 
 tuple_impls! {
+    (CloneableTuple1, ImmutableTuple1) {
+        (n0, n0_ref) -> A { (ref a,) => a }
+    }
+
     (CloneableTuple2, ImmutableTuple2) {
         (n0, n0_ref) -> A { (ref a,_) => a }
         (n1, n1_ref) -> B { (_,ref b) => b }
@@ -432,6 +441,8 @@ mod tests {
     fn test_tuple_cmp() {
         let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
 
+        let nan = 0.0/0.0;
+
         // Eq
         assert_eq!(small, small);
         assert_eq!(big, big);
@@ -452,6 +463,13 @@ mod tests {
         assert!(big >= small);
         assert!(big >= big);
 
+        assert!(!((1.0, 2.0) < (nan, 3.0)));
+        assert!(!((1.0, 2.0) <= (nan, 3.0)));
+        assert!(!((1.0, 2.0) > (nan, 3.0)));
+        assert!(!((1.0, 2.0) >= (nan, 3.0)));
+        assert!(((1.0, 2.0) < (2.0, nan)));
+        assert!(!((2.0, 2.0) < (2.0, nan)));
+
         // TotalEq
         assert!(small.equals(&small));
         assert!(big.equals(&big));
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index d626b8604db..2228922d9e4 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -564,17 +564,19 @@ pub mod traits {
     use super::*;
 
     use clone::Clone;
-    use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv};
+    use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv};
+    use iterator::order;
     use ops::Add;
-    use option::{Some, None};
 
     impl<'self,T:Eq> Eq for &'self [T] {
         fn eq(&self, other: & &'self [T]) -> bool {
             self.len() == other.len() &&
-                self.iter().zip(other.iter()).all(|(s,o)| *s == *o)
+                order::eq(self.iter(), other.iter())
+        }
+        fn ne(&self, other: & &'self [T]) -> bool {
+            self.len() != other.len() ||
+                order::ne(self.iter(), other.iter())
         }
-        #[inline]
-        fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
     }
 
     impl<T:Eq> Eq for ~[T] {
@@ -594,7 +596,7 @@ pub mod traits {
     impl<'self,T:TotalEq> TotalEq for &'self [T] {
         fn equals(&self, other: & &'self [T]) -> bool {
             self.len() == other.len() &&
-                self.iter().zip(other.iter()).all(|(s,o)| s.equals(o))
+                order::equals(self.iter(), other.iter())
         }
     }
 
@@ -625,13 +627,7 @@ pub mod traits {
 
     impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
         fn cmp(&self, other: & &'self [T]) -> Ordering {
-            for (s,o) in self.iter().zip(other.iter()) {
-                match s.cmp(o) {
-                    Equal => {},
-                    non_eq => { return non_eq; }
-                }
-            }
-            self.len().cmp(&other.len())
+            order::cmp(self.iter(), other.iter())
         }
     }
 
@@ -645,23 +641,25 @@ pub mod traits {
         fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
     }
 
-    impl<'self,T:Ord> Ord for &'self [T] {
+    impl<'self, T: Eq + Ord> Ord for &'self [T] {
         fn lt(&self, other: & &'self [T]) -> bool {
-            for (s,o) in self.iter().zip(other.iter()) {
-                if *s < *o { return true; }
-                if *s > *o { return false; }
-            }
-            self.len() < other.len()
+            order::lt(self.iter(), other.iter())
         }
         #[inline]
-        fn le(&self, other: & &'self [T]) -> bool { !(*other < *self) }
+        fn le(&self, other: & &'self [T]) -> bool {
+            order::le(self.iter(), other.iter())
+        }
         #[inline]
-        fn ge(&self, other: & &'self [T]) -> bool { !(*self < *other) }
+        fn ge(&self, other: & &'self [T]) -> bool {
+            order::ge(self.iter(), other.iter())
+        }
         #[inline]
-        fn gt(&self, other: & &'self [T]) -> bool { *other < *self }
+        fn gt(&self, other: & &'self [T]) -> bool {
+            order::gt(self.iter(), other.iter())
+        }
     }
 
-    impl<T:Ord> Ord for ~[T] {
+    impl<T: Eq + Ord> Ord for ~[T] {
         #[inline]
         fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
         #[inline]
@@ -672,7 +670,7 @@ pub mod traits {
         fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
     }
 
-    impl<T:Ord> Ord for @[T] {
+    impl<T: Eq + Ord> Ord for @[T] {
         #[inline]
         fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() }
         #[inline]