about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-06 08:06:50 +0000
committerbors <bors@rust-lang.org>2014-11-06 08:06:50 +0000
commite84e7a00ddec76570bbaa9afea385d544f616814 (patch)
tree5757b1eec689ab03459c9f2518cc602284c44733 /src
parent0e2f9b948564708085373fc28d91b4524c821fa3 (diff)
parent11f4baeafb83459befd0196b2b82cda7ed5ea2f1 (diff)
downloadrust-e84e7a00ddec76570bbaa9afea385d544f616814.tar.gz
rust-e84e7a00ddec76570bbaa9afea385d544f616814.zip
auto merge of #18467 : japaric/rust/eq, r=alexcrichton
`eq`, `ne`, `cmp`, etc methods now require one less level of indirection when dealing with `&str`/`&[T]`

``` rust
"foo".ne(&"bar") -> "foo".ne("bar")
slice.cmp(&another_slice) -> slice.cmp(another_slice)
// slice and another_slice have type `&[T]`
```

[breaking-change]
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/boxed.rs40
-rw-r--r--src/libcollections/slice.rs10
-rw-r--r--src/libcollections/str.rs17
-rw-r--r--src/libcollections/tree/map.rs14
-rw-r--r--src/libcollections/vec.rs14
-rw-r--r--src/libcore/cmp.rs222
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/libcore/result.rs1
-rw-r--r--src/libcore/slice.rs62
-rw-r--r--src/libcore/str.rs48
-rw-r--r--src/libgetopts/lib.rs1
-rw-r--r--src/libgraphviz/maybe_owned_vec.rs12
-rw-r--r--src/libregex/parse.rs10
-rw-r--r--src/librustc/driver/mod.rs28
-rw-r--r--src/librustrt/c_str.rs7
-rw-r--r--src/libserialize/json.rs38
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs36
-rw-r--r--src/libsyntax/util/interner.rs6
-rw-r--r--src/libtest/lib.rs50
-rw-r--r--src/test/compile-fail/deriving-no-inner-impl-error-message.rs4
-rw-r--r--src/test/run-pass/deriving-eq-ord-boxed-slice.rs24
-rw-r--r--src/test/run-pass/issue-15689-1.rs18
22 files changed, 635 insertions, 29 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index de98bc63183..d1fc921ffda 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -61,12 +61,16 @@ impl<T: Clone> Clone for Box<T> {
     }
 }
 
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 impl<T:PartialEq> PartialEq for Box<T> {
     #[inline]
     fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
     #[inline]
     fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
 }
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 impl<T:PartialOrd> PartialOrd for Box<T> {
     #[inline]
     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
@@ -81,14 +85,50 @@ impl<T:PartialOrd> PartialOrd for Box<T> {
     #[inline]
     fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
 }
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 impl<T: Ord> Ord for Box<T> {
     #[inline]
     fn cmp(&self, other: &Box<T>) -> Ordering {
         (**self).cmp(&**other)
     }
 }
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 impl<T: Eq> Eq for Box<T> {}
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+impl<Sized? T: PartialEq> PartialEq for Box<T> {
+    #[inline]
+    fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
+    #[inline]
+    fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
+}
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&**self, &**other)
+    }
+    #[inline]
+    fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
+    #[inline]
+    fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
+    #[inline]
+    fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
+    #[inline]
+    fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
+}
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+impl<Sized? T: Ord> Ord for Box<T> {
+    #[inline]
+    fn cmp(&self, other: &Box<T>) -> Ordering {
+        Ord::cmp(&**self, &**other)
+    }
+}
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+impl<Sized? T: Eq> Eq for Box<T> {}
+
 /// Extension methods for an owning `Any` trait object.
 #[unstable = "post-DST and coherence changes, this will not be a trait but \
               rather a direct `impl` on `Box<Any>`"]
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index eb4ff345b51..e4af5795e1c 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -1598,15 +1598,15 @@ mod tests {
     #[test]
     fn test_total_ord() {
         let c: &[int] = &[1, 2, 3];
-        [1, 2, 3, 4][].cmp(& c) == Greater;
+        [1, 2, 3, 4][].cmp(c) == Greater;
         let c: &[int] = &[1, 2, 3, 4];
-        [1, 2, 3][].cmp(& c) == Less;
+        [1, 2, 3][].cmp(c) == Less;
         let c: &[int] = &[1, 2, 3, 6];
-        [1, 2, 3, 4][].cmp(& c) == Equal;
+        [1, 2, 3, 4][].cmp(c) == Equal;
         let c: &[int] = &[1, 2, 3, 4, 5, 6];
-        [1, 2, 3, 4, 5, 5, 5, 5][].cmp(& c) == Less;
+        [1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less;
         let c: &[int] = &[1, 2, 3, 4];
-        [2, 2][].cmp(& c) == Greater;
+        [2, 2][].cmp(c) == Greater;
     }
 
     #[test]
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index ff756a8eef3..cdca0d10eed 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -532,10 +532,17 @@ impl<'a> PartialOrd for MaybeOwned<'a> {
 }
 
 impl<'a> Ord for MaybeOwned<'a> {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     #[inline]
     fn cmp(&self, other: &MaybeOwned) -> Ordering {
         self.as_slice().cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[inline]
+    fn cmp(&self, other: &MaybeOwned) -> Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
 }
 
 impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
@@ -1523,11 +1530,11 @@ mod tests {
 
     #[test]
     fn test_total_ord() {
-        "1234".cmp(&("123")) == Greater;
-        "123".cmp(&("1234")) == Less;
-        "1234".cmp(&("1234")) == Equal;
-        "12345555".cmp(&("123456")) == Less;
-        "22".cmp(&("1234")) == Greater;
+        "1234".cmp("123") == Greater;
+        "123".cmp("1234") == Less;
+        "1234".cmp("1234") == Equal;
+        "12345555".cmp("123456") == Less;
+        "22".cmp("1234") == Greater;
     }
 
     #[test]
diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs
index 9742bddb1f6..8e24eabfccf 100644
--- a/src/libcollections/tree/map.rs
+++ b/src/libcollections/tree/map.rs
@@ -579,7 +579,7 @@ impl<K, V> TreeMap<K, V> {
     /// let headers = get_headers();
     /// let ua_key = "User-Agent";
     /// let ua = headers.find_with(|k| {
-    ///    ua_key.cmp(&k.as_slice())
+    ///    ua_key.cmp(k.as_slice())
     /// });
     ///
     /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
@@ -603,7 +603,7 @@ impl<K, V> TreeMap<K, V> {
     /// t.insert("User-Agent", "Curl-Rust/0.1");
     ///
     /// let new_ua = "Safari/156.0";
-    /// match t.find_with_mut(|k| "User-Agent".cmp(k)) {
+    /// match t.find_with_mut(|&k| "User-Agent".cmp(k)) {
     ///    Some(x) => *x = new_ua,
     ///    None => panic!(),
     /// }
@@ -1302,7 +1302,7 @@ mod test_treemap {
     #[test]
     fn find_with_empty() {
         let m: TreeMap<&'static str,int> = TreeMap::new();
-        assert!(m.find_with(|k| "test".cmp(k)) == None);
+        assert!(m.find_with(|&k| "test".cmp(k)) == None);
     }
 
     #[test]
@@ -1311,7 +1311,7 @@ mod test_treemap {
         assert!(m.insert("test1", 2i));
         assert!(m.insert("test2", 3i));
         assert!(m.insert("test3", 3i));
-        assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
+        assert_eq!(m.find_with(|&k| "test4".cmp(k)), None);
     }
 
     #[test]
@@ -1320,7 +1320,7 @@ mod test_treemap {
         assert!(m.insert("test1", 2i));
         assert!(m.insert("test2", 3i));
         assert!(m.insert("test3", 4i));
-        assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
+        assert_eq!(m.find_with(|&k| "test2".cmp(k)), Some(&3i));
     }
 
     #[test]
@@ -1343,10 +1343,10 @@ mod test_treemap {
         assert!(m.insert("t2", 8));
         assert!(m.insert("t5", 14));
         let new = 100;
-        match m.find_with_mut(|k| "t5".cmp(k)) {
+        match m.find_with_mut(|&k| "t5".cmp(k)) {
           None => panic!(), Some(x) => *x = new
         }
-        assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
+        assert_eq!(m.find_with(|&k| "t5".cmp(k)), Some(&new));
     }
 
     #[test]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 40e7c949972..4b6921ed0c0 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -506,10 +506,17 @@ impl<T: PartialEq> PartialEq for Vec<T> {
 
 #[unstable = "waiting on PartialOrd stability"]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     #[inline]
     fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
         self.as_slice().partial_cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[inline]
+    fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
+        self.as_slice().partial_cmp(other.as_slice())
+    }
 }
 
 #[unstable = "waiting on Eq stability"]
@@ -523,10 +530,17 @@ impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for Vec<T> {
 
 #[unstable = "waiting on Ord stability"]
 impl<T: Ord> Ord for Vec<T> {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     #[inline]
     fn cmp(&self, other: &Vec<T>) -> Ordering {
         self.as_slice().cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[inline]
+    fn cmp(&self, other: &Vec<T>) -> Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
 }
 
 // FIXME: #13996: need a way to mark the return value as `noalias`
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index d7c2b52b8de..6e87fe4ced0 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -55,6 +55,8 @@ use option::{Option, Some, None};
 ///
 /// Eventually, this will be implemented by default for types that implement
 /// `Eq`.
+// NOTE(stage0): remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="eq"]
 #[unstable = "Definition may change slightly after trait reform"]
 pub trait PartialEq {
@@ -66,6 +68,31 @@ pub trait PartialEq {
     fn ne(&self, other: &Self) -> bool { !self.eq(other) }
 }
 
+/// Trait for values that can be compared for equality and inequality.
+///
+/// This trait allows for partial equality, for types that do not have an
+/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
+/// so floating point types implement `PartialEq` but not `Eq`.
+///
+/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
+/// in terms of it by default. Any manual implementation of `ne` *must* respect
+/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
+/// only if `a != b`.
+///
+/// Eventually, this will be implemented by default for types that implement
+/// `Eq`.
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[lang="eq"]
+#[unstable = "Definition may change slightly after trait reform"]
+pub trait PartialEq for Sized? {
+    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
+    fn eq(&self, other: &Self) -> bool;
+
+    /// This method tests for `!=`.
+    #[inline]
+    fn ne(&self, other: &Self) -> bool { !self.eq(other) }
+}
+
 /// Trait for equality comparisons which are [equivalence relations](
 /// https://en.wikipedia.org/wiki/Equivalence_relation).
 ///
@@ -75,6 +102,8 @@ pub trait PartialEq {
 /// - reflexive: `a == a`;
 /// - symmetric: `a == b` implies `b == a`; and
 /// - transitive: `a == b` and `b == c` implies `a == c`.
+// NOTE(stage0): remove trait after a snapshot
+#[cfg(stage0)]
 #[unstable = "Definition may change slightly after trait reform"]
 pub trait Eq: PartialEq {
     // FIXME #13101: this method is used solely by #[deriving] to
@@ -89,6 +118,30 @@ pub trait Eq: PartialEq {
     fn assert_receiver_is_total_eq(&self) {}
 }
 
+/// Trait for equality comparisons which are [equivalence relations](
+/// https://en.wikipedia.org/wiki/Equivalence_relation).
+///
+/// This means, that in addition to `a == b` and `a != b` being strict
+/// inverses, the equality must be (for all `a`, `b` and `c`):
+///
+/// - reflexive: `a == a`;
+/// - symmetric: `a == b` implies `b == a`; and
+/// - transitive: `a == b` and `b == c` implies `a == c`.
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "Definition may change slightly after trait reform"]
+pub trait Eq for Sized?: PartialEq {
+    // FIXME #13101: this method is used solely by #[deriving] to
+    // assert that every component of a type implements #[deriving]
+    // itself, the current deriving infrastructure means doing this
+    // assertion without using a method on this trait is nearly
+    // impossible.
+    //
+    // This should never be implemented by hand.
+    #[doc(hidden)]
+    #[inline(always)]
+    fn assert_receiver_is_total_eq(&self) {}
+}
+
 /// An ordering is, e.g, a result of a comparison between two values.
 #[deriving(Clone, PartialEq, Show)]
 #[stable]
@@ -145,6 +198,8 @@ impl Ordering {
 ///   true; and
 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
 ///   both `==` and `>`.
+// NOTE(stage0): remove trait after a snapshot
+#[cfg(stage0)]
 #[unstable = "Definition may change slightly after trait reform"]
 pub trait Ord: Eq + PartialOrd {
     /// This method returns an ordering between `self` and `other` values.
@@ -160,6 +215,31 @@ pub trait Ord: Eq + PartialOrd {
     fn cmp(&self, other: &Self) -> Ordering;
 }
 
+/// Trait for types that form a [total order](
+/// https://en.wikipedia.org/wiki/Total_order).
+///
+/// An order is a total order if it is (for all `a`, `b` and `c`):
+///
+/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
+///   true; and
+/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
+///   both `==` and `>`.
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "Definition may change slightly after trait reform"]
+pub trait Ord for Sized?: Eq + PartialOrd {
+    /// This method returns an ordering between `self` and `other` values.
+    ///
+    /// By convention, `self.cmp(&other)` returns the ordering matching
+    /// the expression `self <operator> other` if true.  For example:
+    ///
+    /// ```
+    /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
+    /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
+    /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
+    /// ```
+    fn cmp(&self, other: &Self) -> Ordering;
+}
+
 #[unstable = "Trait is unstable."]
 impl Eq for Ordering {}
 
@@ -188,6 +268,8 @@ impl PartialOrd for Ordering {
 /// which do not have a total order. For example, for floating point numbers,
 /// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
 /// 5.11).
+// NOTE(stage0): remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="ord"]
 #[unstable = "Definition may change slightly after trait reform"]
 pub trait PartialOrd: PartialEq {
@@ -232,6 +314,60 @@ pub trait PartialOrd: PartialEq {
     }
 }
 
+/// Trait for values that can be compared for a sort-order.
+///
+/// PartialOrd only requires implementation of the `partial_cmp` method,
+/// with the others generated from default implementations.
+///
+/// However it remains possible to implement the others separately for types
+/// which do not have a total order. For example, for floating point numbers,
+/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
+/// 5.11).
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[lang="ord"]
+#[unstable = "Definition may change slightly after trait reform"]
+pub trait PartialOrd for Sized?: PartialEq {
+    /// This method returns an ordering between `self` and `other` values
+    /// if one exists.
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
+
+    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+    #[inline]
+    fn lt(&self, other: &Self) -> bool {
+        match self.partial_cmp(other) {
+            Some(Less) => true,
+            _ => false,
+        }
+    }
+
+    /// This method tests less than or equal to (`<=`).
+    #[inline]
+    fn le(&self, other: &Self) -> bool {
+        match self.partial_cmp(other) {
+            Some(Less) | Some(Equal) => true,
+            _ => false,
+        }
+    }
+
+    /// This method tests greater than (`>`).
+    #[inline]
+    fn gt(&self, other: &Self) -> bool {
+        match self.partial_cmp(other) {
+            Some(Greater) => true,
+            _ => false,
+        }
+    }
+
+    /// This method tests greater than or equal to (`>=`).
+    #[inline]
+    fn ge(&self, other: &Self) -> bool {
+        match self.partial_cmp(other) {
+            Some(Greater) | Some(Equal) => true,
+            _ => false,
+        }
+    }
+}
+
 /// The equivalence relation. Two values may be equivalent even if they are
 /// of different types. The most common use case for this relation is
 /// container types; e.g. it is often desirable to be able to use `&str`
@@ -286,6 +422,8 @@ pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 mod impls {
     use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
               Less, Greater, Equal};
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    use kinds::Sized;
     use option::{Option, Some, None};
 
     macro_rules! partial_eq_impl(
@@ -393,6 +531,8 @@ mod impls {
     ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
     // & pointers
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: PartialEq> PartialEq for &'a T {
         #[inline]
@@ -400,6 +540,8 @@ mod impls {
         #[inline]
         fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: PartialOrd> PartialOrd for &'a T {
         #[inline]
@@ -415,15 +557,55 @@ mod impls {
         #[inline]
         fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: Ord> Ord for &'a T {
         #[inline]
         fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: Eq> Eq for &'a T {}
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: PartialEq> PartialEq for &'a T {
+        #[inline]
+        fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) }
+        #[inline]
+        fn ne(&self, other: & &'a T) -> bool { PartialEq::ne(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T {
+        #[inline]
+        fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
+            PartialOrd::partial_cmp(*self, *other)
+        }
+        #[inline]
+        fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) }
+        #[inline]
+        fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) }
+        #[inline]
+        fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) }
+        #[inline]
+        fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: Ord> Ord for &'a T {
+        #[inline]
+        fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: Eq> Eq for &'a T {}
+
     // &mut pointers
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: PartialEq> PartialEq for &'a mut T {
         #[inline]
@@ -431,6 +613,8 @@ mod impls {
         #[inline]
         fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
         #[inline]
@@ -446,11 +630,49 @@ mod impls {
         #[inline]
         fn gt(&self, other: &&'a mut T) -> bool { **self > **other }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: Ord> Ord for &'a mut T {
         #[inline]
         fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
     }
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     #[unstable = "Trait is unstable."]
     impl<'a, T: Eq> Eq for &'a mut T {}
+
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: PartialEq> PartialEq for &'a mut T {
+        #[inline]
+        fn eq(&self, other: &&'a mut T) -> bool { PartialEq::eq(*self, *other) }
+        #[inline]
+        fn ne(&self, other: &&'a mut T) -> bool { PartialEq::ne(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T {
+        #[inline]
+        fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
+            PartialOrd::partial_cmp(*self, *other)
+        }
+        #[inline]
+        fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) }
+        #[inline]
+        fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) }
+        #[inline]
+        fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) }
+        #[inline]
+        fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: Ord> Ord for &'a mut T {
+        #[inline]
+        fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) }
+    }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[unstable = "Trait is unstable."]
+    impl<'a, Sized? T: Eq> Eq for &'a mut T {}
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index b787de4423a..2964a6b6853 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -143,7 +143,7 @@
 
 #![stable]
 
-use cmp::{PartialEq, Eq, Ord};
+use cmp::{Eq, Ord};
 use default::Default;
 use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
 use mem;
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 2ad5521bb76..c4cb2987241 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -276,7 +276,6 @@
 
 #![stable]
 
-use cmp::PartialEq;
 use std::fmt::Show;
 use slice;
 use slice::AsSlice;
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 317a6e224bc..3cc904162a1 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1555,6 +1555,8 @@ pub mod bytes {
 // Boilerplate traits
 //
 
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a,T:PartialEq> PartialEq for &'a [T] {
     fn eq(&self, other: & &'a [T]) -> bool {
@@ -1567,15 +1569,36 @@ impl<'a,T:PartialEq> PartialEq for &'a [T] {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "waiting for DST"]
+impl<T: PartialEq> PartialEq for [T] {
+    fn eq(&self, other: &[T]) -> bool {
+        self.len() == other.len() &&
+            order::eq(self.iter(), other.iter())
+    }
+    fn ne(&self, other: &[T]) -> bool {
+        self.len() != other.len() ||
+            order::ne(self.iter(), other.iter())
+    }
+}
+
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a,T:Eq> Eq for &'a [T] {}
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "waiting for DST"]
+impl<T: Eq> Eq for [T] {}
+
 #[unstable = "waiting for DST"]
 impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for [T] {
     #[inline]
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a,T:PartialEq> PartialEq for &'a mut [T] {
     fn eq(&self, other: & &'a mut [T]) -> bool {
@@ -1588,6 +1611,8 @@ impl<'a,T:PartialEq> PartialEq for &'a mut [T] {
     }
 }
 
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a,T:Eq> Eq for &'a mut [T] {}
 
@@ -1597,6 +1622,8 @@ impl<'a,T:PartialEq, V: AsSlice<T>> Equiv<V> for &'a mut [T] {
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a,T:Ord> Ord for &'a [T] {
     fn cmp(&self, other: & &'a [T]) -> Ordering {
@@ -1604,6 +1631,16 @@ impl<'a,T:Ord> Ord for &'a [T] {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "waiting for DST"]
+impl<T: Ord> Ord for [T] {
+    fn cmp(&self, other: &[T]) -> Ordering {
+        order::cmp(self.iter(), other.iter())
+    }
+}
+
+// NOTE(stage0): remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "waiting for DST"]
 impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
     #[inline]
@@ -1628,6 +1665,31 @@ impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[unstable = "waiting for DST"]
+impl<T: PartialOrd> PartialOrd for [T] {
+    #[inline]
+    fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
+        order::partial_cmp(self.iter(), other.iter())
+    }
+    #[inline]
+    fn lt(&self, other: &[T]) -> bool {
+        order::lt(self.iter(), other.iter())
+    }
+    #[inline]
+    fn le(&self, other: &[T]) -> bool {
+        order::le(self.iter(), other.iter())
+    }
+    #[inline]
+    fn ge(&self, other: &[T]) -> bool {
+        order::ge(self.iter(), other.iter())
+    }
+    #[inline]
+    fn gt(&self, other: &[T]) -> bool {
+        order::gt(self.iter(), other.iter())
+    }
+}
+
 /// Extension methods for immutable slices containing integers.
 #[experimental]
 pub trait ImmutableIntSlice<U, S> for Sized? {
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 8937f2a946a..175f9f3f577 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -19,8 +19,7 @@
 use mem;
 use char;
 use char::Char;
-use cmp;
-use cmp::{PartialEq, Eq};
+use cmp::{Eq, mod};
 use default::Default;
 use iter::{Map, Iterator};
 use iter::{DoubleEndedIterator, ExactSize};
@@ -1123,6 +1122,8 @@ pub mod traits {
     use ops;
     use str::{Str, StrSlice, eq_slice};
 
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     impl<'a> Ord for &'a str {
         #[inline]
         fn cmp(&self, other: & &'a str) -> Ordering {
@@ -1138,6 +1139,24 @@ pub mod traits {
         }
     }
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    impl Ord for str {
+        #[inline]
+        fn cmp(&self, other: &str) -> Ordering {
+            for (s_b, o_b) in self.bytes().zip(other.bytes()) {
+                match s_b.cmp(&o_b) {
+                    Greater => return Greater,
+                    Less => return Less,
+                    Equal => ()
+                }
+            }
+
+            self.len().cmp(&other.len())
+        }
+    }
+
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     impl<'a> PartialEq for &'a str {
         #[inline]
         fn eq(&self, other: & &'a str) -> bool {
@@ -1147,8 +1166,25 @@ pub mod traits {
         fn ne(&self, other: & &'a str) -> bool { !(*self).eq(other) }
     }
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    impl PartialEq for str {
+        #[inline]
+        fn eq(&self, other: &str) -> bool {
+            eq_slice(self, other)
+        }
+        #[inline]
+        fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
+    }
+
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     impl<'a> Eq for &'a str {}
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    impl Eq for str {}
+
+    // NOTE(stage0): remove impl after a snapshot
+    #[cfg(stage0)]
     impl<'a> PartialOrd for &'a str {
         #[inline]
         fn partial_cmp(&self, other: &&'a str) -> Option<Ordering> {
@@ -1156,6 +1192,14 @@ pub mod traits {
         }
     }
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    impl PartialOrd for str {
+        #[inline]
+        fn partial_cmp(&self, other: &str) -> Option<Ordering> {
+            Some(self.cmp(other))
+        }
+    }
+
     impl<S: Str> Equiv<S> for str {
         #[inline]
         fn equiv(&self, other: &S) -> bool { eq_slice(self, other.as_slice()) }
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index a8a91283a11..d60835dff17 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -93,7 +93,6 @@
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
-use std::cmp::PartialEq;
 use std::fmt;
 use std::result::{Err, Ok};
 use std::result;
diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs
index d465d140751..3a89d8b3f81 100644
--- a/src/libgraphviz/maybe_owned_vec.rs
+++ b/src/libgraphviz/maybe_owned_vec.rs
@@ -76,15 +76,27 @@ impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> {
 impl<'a, T: Eq> Eq for MaybeOwnedVector<'a, T> {}
 
 impl<'a, T: PartialOrd> PartialOrd for MaybeOwnedVector<'a, T> {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     fn partial_cmp(&self, other: &MaybeOwnedVector<T>) -> Option<Ordering> {
         self.as_slice().partial_cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    fn partial_cmp(&self, other: &MaybeOwnedVector<T>) -> Option<Ordering> {
+        self.as_slice().partial_cmp(other.as_slice())
+    }
 }
 
 impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     fn cmp(&self, other: &MaybeOwnedVector<T>) -> Ordering {
         self.as_slice().cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    fn cmp(&self, other: &MaybeOwnedVector<T>) -> Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
 }
 
 impl<'a, T: PartialEq, V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
index 3115161682f..6723ea725a3 100644
--- a/src/libregex/parse.rs
+++ b/src/libregex/parse.rs
@@ -1020,6 +1020,8 @@ fn is_valid_cap(c: char) -> bool {
     || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
 }
 
+// NOTE(stage0): remove function after a snapshot
+#[cfg(stage0)]
 fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
     match classes.binary_search(|&(s, _)| s.cmp(&name)) {
         slice::Found(i) => Some(classes[i].val1().to_vec()),
@@ -1027,6 +1029,14 @@ fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
+    match classes.binary_search(|&(s, _)| s.cmp(name)) {
+        slice::Found(i) => Some(classes[i].val1().to_vec()),
+        slice::NotFound(_) => None,
+    }
+}
+
 type Class = &'static [(char, char)];
 type NamedClasses = &'static [(&'static str, &'static Class)];
 
diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs
index 7715f0e10f5..8753795d9e2 100644
--- a/src/librustc/driver/mod.rs
+++ b/src/librustc/driver/mod.rs
@@ -182,6 +182,8 @@ Available lint options:
 
 ");
 
+    // NOTE(stage0): remove function after a snapshot
+    #[cfg(stage0)]
     fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
         let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
         lints.sort_by(|x: &&Lint, y: &&Lint| {
@@ -194,6 +196,21 @@ Available lint options:
         lints
     }
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
+        let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
+        lints.sort_by(|x: &&Lint, y: &&Lint| {
+            match x.default_level.cmp(&y.default_level) {
+                // The sort doesn't case-fold but it's doubtful we care.
+                Equal => x.name.cmp(y.name),
+                r => r,
+            }
+        });
+        lints
+    }
+
+    // NOTE(stage0): remove function after a snapshot
+    #[cfg(stage0)]
     fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
                      -> Vec<(&'static str, Vec<lint::LintId>)> {
         let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect();
@@ -204,6 +221,17 @@ Available lint options:
         lints
     }
 
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
+                     -> Vec<(&'static str, Vec<lint::LintId>)> {
+        let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect();
+        lints.sort_by(|&(x, _): &(&'static str, Vec<lint::LintId>),
+                       &(y, _): &(&'static str, Vec<lint::LintId>)| {
+            x.cmp(y)
+        });
+        lints
+    }
+
     let (plugin, builtin) = lint_store.get_lints().partitioned(|&(_, p)| p);
     let plugin = sort_lints(plugin);
     let builtin = sort_lints(builtin);
diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index b15cdb88b67..b7a2c8f9473 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -121,10 +121,17 @@ impl PartialEq for CString {
 }
 
 impl PartialOrd for CString {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     #[inline]
     fn partial_cmp(&self, other: &CString) -> Option<Ordering> {
         self.as_bytes().partial_cmp(&other.as_bytes())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    #[inline]
+    fn partial_cmp(&self, other: &CString) -> Option<Ordering> {
+        self.as_bytes().partial_cmp(other.as_bytes())
+    }
 }
 
 impl Eq for CString {}
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index e0d436f5e0e..dbdfa17bfc2 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -890,6 +890,8 @@ impl Json {
 
      /// If the Json value is an Object, returns the value associated with the provided key.
     /// Otherwise, returns None.
+    // NOTE(stage0): remove function after a snapshot
+    #[cfg(stage0)]
     pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
         match self {
             &Object(ref map) => map.find_with(|s| key.cmp(&s.as_slice())),
@@ -897,6 +899,16 @@ impl Json {
         }
     }
 
+     /// If the Json value is an Object, returns the value associated with the provided key.
+    /// Otherwise, returns None.
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
+        match self {
+            &Object(ref map) => map.find_with(|s| key.cmp(s.as_slice())),
+            _ => None
+        }
+    }
+
     /// Attempts to get a nested Json Object for each key in `keys`.
     /// If any key is found not to exist, find_path will return None.
     /// Otherwise, it will return the Json value associated with the final key.
@@ -914,6 +926,8 @@ impl Json {
     /// If the Json value is an Object, performs a depth-first search until
     /// a value associated with the provided key is found. If no value is found
     /// or the Json value is not an Object, returns None.
+    // NOTE(stage0): remove function after a snapshot
+    #[cfg(stage0)]
     pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
         match self {
             &Object(ref map) => {
@@ -934,6 +948,30 @@ impl Json {
         }
     }
 
+    /// If the Json value is an Object, performs a depth-first search until
+    /// a value associated with the provided key is found. If no value is found
+    /// or the Json value is not an Object, returns None.
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
+        match self {
+            &Object(ref map) => {
+                match map.find_with(|s| key.cmp(s.as_slice())) {
+                    Some(json_value) => Some(json_value),
+                    None => {
+                        for (_, v) in map.iter() {
+                            match v.search(key) {
+                                x if x.is_some() => return x,
+                                _ => ()
+                            }
+                        }
+                        None
+                    }
+                }
+            },
+            _ => None
+        }
+    }
+
     /// Returns true if the Json value is an Object. Returns false otherwise.
     pub fn is_object<'a>(&'a self) -> bool {
         self.as_object().is_some()
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index a27016fde61..c3b1a52925d 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{MetaItem, Item, Expr};
+use ast::{MetaItem, Item, Expr, mod};
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -25,12 +25,38 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
     fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
-        cs_and(|cx, span, _, _| cx.expr_bool(span, false),
-                                 cx, span, substr)
+        cs_fold(
+            true,  // use foldl
+            |cx, span, subexpr, self_f, other_fs| {
+                let other_f = match other_fs {
+                    [ref o_f] => o_f,
+                    _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Eq)`")
+                };
+
+                let eq = cx.expr_binary(span, ast::BiEq, self_f, other_f.clone());
+
+                cx.expr_binary(span, ast::BiAnd, subexpr, eq)
+            },
+            cx.expr_bool(span, true),
+            |cx, span, _, _| cx.expr_bool(span, false),
+            cx, span, substr)
     }
     fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
-        cs_or(|cx, span, _, _| cx.expr_bool(span, true),
-              cx, span, substr)
+        cs_fold(
+            true,  // use foldl
+            |cx, span, subexpr, self_f, other_fs| {
+                let other_f = match other_fs {
+                    [ref o_f] => o_f,
+                    _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Eq)`")
+                };
+
+                let eq = cx.expr_binary(span, ast::BiNe, self_f, other_f.clone());
+
+                cx.expr_binary(span, ast::BiOr, subexpr, eq)
+            },
+            cx.expr_bool(span, false),
+            |cx, span, _, _| cx.expr_bool(span, true),
+            cx, span, substr)
     }
 
     macro_rules! md (
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 105118ff76a..e6c98a9e3d0 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -97,9 +97,15 @@ pub struct RcStr {
 impl Eq for RcStr {}
 
 impl Ord for RcStr {
+    // NOTE(stage0): remove method after a snapshot
+    #[cfg(stage0)]
     fn cmp(&self, other: &RcStr) -> Ordering {
         self.as_slice().cmp(&other.as_slice())
     }
+    #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+    fn cmp(&self, other: &RcStr) -> Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
 }
 
 impl Str for RcStr {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 81d0bb76d14..74bead9e5f2 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -973,6 +973,8 @@ fn get_concurrency() -> uint {
     }
 }
 
+// NOTE(stage0): remove function after a snapshot
+#[cfg(stage0)]
 pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
     let mut filtered = tests;
 
@@ -1020,6 +1022,54 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
+    let mut filtered = tests;
+
+    // Remove tests that don't match the test filter
+    filtered = match opts.filter {
+        None => filtered,
+        Some(ref re) => {
+            filtered.into_iter()
+                .filter(|test| re.is_match(test.desc.name.as_slice())).collect()
+        }
+    };
+
+    // Maybe pull out the ignored test and unignore them
+    filtered = if !opts.run_ignored {
+        filtered
+    } else {
+        fn filter(test: TestDescAndFn) -> Option<TestDescAndFn> {
+            if test.desc.ignore {
+                let TestDescAndFn {desc, testfn} = test;
+                Some(TestDescAndFn {
+                    desc: TestDesc {ignore: false, ..desc},
+                    testfn: testfn
+                })
+            } else {
+                None
+            }
+        };
+        filtered.into_iter().filter_map(|x| filter(x)).collect()
+    };
+
+    // Sort the tests alphabetically
+    filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice()));
+
+    // Shard the remaining tests, if sharding requested.
+    match opts.test_shard {
+        None => filtered,
+        Some((a,b)) => {
+            filtered.into_iter().enumerate()
+            // note: using a - 1 so that the valid shards, for example, are
+            // 1.2 and 2.2 instead of 0.2 and 1.2
+            .filter(|&(i,_)| i % b == (a - 1))
+            .map(|(_,t)| t)
+            .collect()
+        }
+    }
+}
+
 pub fn run_test(opts: &TestOpts,
                 force_ignore: bool,
                 test: TestDescAndFn,
diff --git a/src/test/compile-fail/deriving-no-inner-impl-error-message.rs b/src/test/compile-fail/deriving-no-inner-impl-error-message.rs
index 15a7bc01c3a..18be03f97d9 100644
--- a/src/test/compile-fail/deriving-no-inner-impl-error-message.rs
+++ b/src/test/compile-fail/deriving-no-inner-impl-error-message.rs
@@ -12,8 +12,8 @@ struct NoCloneOrEq;
 
 #[deriving(PartialEq)]
 struct E {
-    x: NoCloneOrEq //~ ERROR does not implement any method in scope named `eq`
-         //~^ ERROR does not implement any method in scope named `ne`
+    x: NoCloneOrEq //~ ERROR binary operation `==` cannot be applied to type `NoCloneOrEq`
+         //~^ ERROR binary operation `!=` cannot be applied to type `NoCloneOrEq`
 }
 #[deriving(Clone)]
 struct C {
diff --git a/src/test/run-pass/deriving-eq-ord-boxed-slice.rs b/src/test/run-pass/deriving-eq-ord-boxed-slice.rs
new file mode 100644
index 00000000000..b16c2ccb46e
--- /dev/null
+++ b/src/test/run-pass/deriving-eq-ord-boxed-slice.rs
@@ -0,0 +1,24 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deriving(PartialEq, PartialOrd, Eq, Ord)]
+struct Foo(Box<[u8]>);
+
+pub fn main() {
+    let a = Foo(box [0, 1, 2]);
+    let b = Foo(box [0, 1, 2]);
+    assert!(a == b);
+    println!("{}", a != b);
+    println!("{}", a < b);
+    println!("{}", a <= b);
+    println!("{}", a == b);
+    println!("{}", a > b);
+    println!("{}", a >= b);
+}
diff --git a/src/test/run-pass/issue-15689-1.rs b/src/test/run-pass/issue-15689-1.rs
new file mode 100644
index 00000000000..8d17fc46006
--- /dev/null
+++ b/src/test/run-pass/issue-15689-1.rs
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deriving(PartialEq)]
+enum Test<'a> {
+    Slice(&'a int)
+}
+
+fn main() {
+    assert!(Slice(&1) == Slice(&1))
+}