Stabilize cmp

This patch marks `PartialEq`, `Eq`, `PartialOrd`, and `Ord` as
`#[stable]`, as well as the majorify of manual implementaitons of these
traits. The traits match the [reform
RFC](https://github.com/rust-lang/rfcs/pull/439).

Along the way, two changes are made:

* The recently-added type parameters for `Ord` and `Eq` are
  removed. These were mistakenly added while adding them to `PartialOrd`
  and `PartialEq`, but they don't make sense given the laws that are
  required for (and use cases for) `Ord` and `Eq`.

* More explicit laws are added for `PartialEq` and `PartialOrd`,
  connecting them to their associated mathematical concepts.

In the future, many of the impls should be generalized; see
since generalizing later is not a breaking change.

[breaking-change]
This commit is contained in:
Aaron Turon 2014-12-30 14:44:26 -08:00
parent 84f5ad8679
commit b94bcbf56e
20 changed files with 182 additions and 83 deletions

View File

@ -458,7 +458,7 @@ impl<T: Sync + Send> Drop for Weak<T> {
}
}
#[unstable = "waiting on PartialEq"]
#[stable]
impl<T: PartialEq> PartialEq for Arc<T> {
/// Equality for two `Arc<T>`s.
///
@ -490,7 +490,7 @@ impl<T: PartialEq> PartialEq for Arc<T> {
/// ```
fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
}
#[unstable = "waiting on PartialOrd"]
#[stable]
impl<T: PartialOrd> PartialOrd for Arc<T> {
/// Partial comparison for two `Arc<T>`s.
///
@ -569,11 +569,11 @@ impl<T: PartialOrd> PartialOrd for Arc<T> {
/// ```
fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
}
#[unstable = "waiting on Ord"]
#[stable]
impl<T: Ord> Ord for Arc<T> {
fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
}
#[unstable = "waiting on Eq"]
#[stable]
impl<T: Eq> Eq for Arc<T> {}
impl<T: fmt::Show> fmt::Show for Arc<T> {

View File

@ -72,12 +72,14 @@ impl<T: Clone> Clone for Box<T> {
}
}
#[stable]
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) }
}
#[stable]
impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
#[inline]
fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
@ -92,12 +94,14 @@ impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
#[inline]
fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
}
#[stable]
impl<Sized? T: Ord> Ord for Box<T> {
#[inline]
fn cmp(&self, other: &Box<T>) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
#[stable]}
impl<Sized? T: Eq> Eq for Box<T> {}
impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {

View File

@ -452,7 +452,7 @@ impl<T: Default> Default for Rc<T> {
}
}
#[unstable = "PartialEq is unstable."]
#[stable]
impl<T: PartialEq> PartialEq for Rc<T> {
/// Equality for two `Rc<T>`s.
///
@ -487,10 +487,10 @@ impl<T: PartialEq> PartialEq for Rc<T> {
fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
}
#[unstable = "Eq is unstable."]
#[stable]
impl<T: Eq> Eq for Rc<T> {}
#[unstable = "PartialOrd is unstable."]
#[stable]
impl<T: PartialOrd> PartialOrd for Rc<T> {
/// Partial comparison for two `Rc<T>`s.
///
@ -575,7 +575,7 @@ impl<T: PartialOrd> PartialOrd for Rc<T> {
fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
}
#[unstable = "Ord is unstable."]
#[stable]
impl<T: Ord> Ord for Rc<T> {
/// Comparison for two `Rc<T>`s.
///

View File

@ -965,6 +965,7 @@ impl Clone for Bitv {
}
}
#[stable]
impl PartialOrd for Bitv {
#[inline]
fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
@ -972,6 +973,7 @@ impl PartialOrd for Bitv {
}
}
#[stable]
impl Ord for Bitv {
#[inline]
fn cmp(&self, other: &Bitv) -> Ordering {
@ -997,6 +999,7 @@ impl<S: hash::Writer> hash::Hash<S> for Bitv {
}
}
#[stable]
impl cmp::PartialEq for Bitv {
#[inline]
fn eq(&self, other: &Bitv) -> bool {
@ -1007,6 +1010,7 @@ impl cmp::PartialEq for Bitv {
}
}
#[stable]
impl cmp::Eq for Bitv {}
/// An iterator for `Bitv`.
@ -1129,6 +1133,7 @@ impl Extend<uint> for BitvSet {
}
}
#[stable]
impl PartialOrd for BitvSet {
#[inline]
fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
@ -1137,6 +1142,7 @@ impl PartialOrd for BitvSet {
}
}
#[stable]
impl Ord for BitvSet {
#[inline]
fn cmp(&self, other: &BitvSet) -> Ordering {
@ -1145,6 +1151,7 @@ impl Ord for BitvSet {
}
}
#[stable]
impl cmp::PartialEq for BitvSet {
#[inline]
fn eq(&self, other: &BitvSet) -> bool {
@ -1153,6 +1160,7 @@ impl cmp::PartialEq for BitvSet {
}
}
#[stable]
impl cmp::Eq for BitvSet {}
impl BitvSet {

View File

@ -843,6 +843,7 @@ impl<K: Ord, V> Default for BTreeMap<K, V> {
}
}
#[stable]
impl<K: PartialEq, V: PartialEq> PartialEq for BTreeMap<K, V> {
fn eq(&self, other: &BTreeMap<K, V>) -> bool {
self.len() == other.len() &&
@ -850,8 +851,10 @@ impl<K: PartialEq, V: PartialEq> PartialEq for BTreeMap<K, V> {
}
}
#[stable]
impl<K: Eq, V: Eq> Eq for BTreeMap<K, V> {}
#[stable]
impl<K: PartialOrd, V: PartialOrd> PartialOrd for BTreeMap<K, V> {
#[inline]
fn partial_cmp(&self, other: &BTreeMap<K, V>) -> Option<Ordering> {
@ -859,6 +862,7 @@ impl<K: PartialOrd, V: PartialOrd> PartialOrd for BTreeMap<K, V> {
}
}
#[stable]
impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
#[inline]
fn cmp(&self, other: &BTreeMap<K, V>) -> Ordering {

View File

@ -770,6 +770,7 @@ impl<A> Extend<A> for DList<A> {
}
}
#[stable]
impl<A: PartialEq> PartialEq for DList<A> {
fn eq(&self, other: &DList<A>) -> bool {
self.len() == other.len() &&
@ -782,14 +783,17 @@ impl<A: PartialEq> PartialEq for DList<A> {
}
}
#[stable]
impl<A: Eq> Eq for DList<A> {}
#[stable]
impl<A: PartialOrd> PartialOrd for DList<A> {
fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}
#[stable]
impl<A: Ord> Ord for DList<A> {
#[inline]
fn cmp(&self, other: &DList<A>) -> Ordering {

View File

@ -1290,6 +1290,7 @@ impl<'a, T: 'a> DoubleEndedIterator<T> for Drain<'a, T> {
impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
#[stable]
impl<A: PartialEq> PartialEq for RingBuf<A> {
fn eq(&self, other: &RingBuf<A>) -> bool {
self.len() == other.len() &&
@ -1297,14 +1298,17 @@ impl<A: PartialEq> PartialEq for RingBuf<A> {
}
}
#[stable]
impl<A: Eq> Eq for RingBuf<A> {}
#[stable]
impl<A: PartialOrd> PartialOrd for RingBuf<A> {
fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}
#[stable]
impl<A: Ord> Ord for RingBuf<A> {
#[inline]
fn cmp(&self, other: &RingBuf<A>) -> Ordering {

View File

@ -815,6 +815,7 @@ impl<'a> Extend<&'a str> for String {
}
}
#[stable]
impl PartialEq for String {
#[inline]
fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
@ -824,6 +825,7 @@ impl PartialEq for String {
macro_rules! impl_eq {
($lhs:ty, $rhs: ty) => {
#[stable]
impl<'a> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@ -831,6 +833,7 @@ macro_rules! impl_eq {
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable]
impl<'a> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
@ -844,6 +847,7 @@ macro_rules! impl_eq {
impl_eq! { String, &'a str }
impl_eq! { CowString<'a>, String }
#[stable]
impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
#[inline]
fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
@ -851,6 +855,7 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable]
impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
#[inline]
fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }

View File

@ -588,6 +588,7 @@ impl<T> Extend<T> for Vec<T> {
}
}
#[stable]
impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
@ -597,6 +598,7 @@ impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
macro_rules! impl_eq {
($lhs:ty, $rhs:ty) => {
#[stable]
impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@ -604,6 +606,7 @@ macro_rules! impl_eq {
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable]
impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
#[inline]
fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
@ -616,6 +619,7 @@ macro_rules! impl_eq {
impl_eq! { Vec<A>, &'b [B] }
impl_eq! { Vec<A>, &'b mut [B] }
#[stable]
impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
#[inline]
fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
@ -623,6 +627,7 @@ impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone
fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable]
impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
#[inline]
fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
@ -632,6 +637,7 @@ impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<
macro_rules! impl_eq_for_cowvec {
($rhs:ty) => {
#[stable]
impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@ -639,6 +645,7 @@ macro_rules! impl_eq_for_cowvec {
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
#[stable]
impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
#[inline]
fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
@ -651,7 +658,7 @@ macro_rules! impl_eq_for_cowvec {
impl_eq_for_cowvec! { &'b [B] }
impl_eq_for_cowvec! { &'b mut [B] }
#[unstable = "waiting on PartialOrd stability"]
#[stable]
impl<T: PartialOrd> PartialOrd for Vec<T> {
#[inline]
fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
@ -659,7 +666,7 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
}
}
#[unstable = "waiting on Eq stability"]
#[stable]
impl<T: Eq> Eq for Vec<T> {}
#[allow(deprecated)]
@ -669,7 +676,7 @@ impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[unstable = "waiting on Ord stability"]
#[stable]
impl<T: Ord> Ord for Vec<T> {
#[inline]
fn cmp(&self, other: &Vec<T>) -> Ordering {

View File

@ -537,14 +537,18 @@ impl<V:Clone> VecMap<V> {
}
}
#[stable]
impl<V: PartialEq> PartialEq for VecMap<V> {
fn eq(&self, other: &VecMap<V>) -> bool {
iter::order::eq(self.iter(), other.iter())
}
}
#[stable]
impl<V: Eq> Eq for VecMap<V> {}
#[stable]
impl<V: PartialOrd> PartialOrd for VecMap<V> {
#[inline]
fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
@ -552,6 +556,7 @@ impl<V: PartialOrd> PartialOrd for VecMap<V> {
}
}
#[stable]
impl<V: Ord> Ord for VecMap<V> {
#[inline]
fn cmp(&self, other: &VecMap<V>) -> Ordering {

View File

@ -39,7 +39,7 @@ macro_rules! array_impls {
}
}
#[unstable = "waiting for PartialEq to stabilize"]
#[stable]
impl<A, B> PartialEq<[B, ..$N]> for [A, ..$N] where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &[B, ..$N]) -> bool {
@ -51,6 +51,7 @@ macro_rules! array_impls {
}
}
#[stable]
impl<'a, A, B, Rhs> PartialEq<Rhs> for [A, ..$N] where
A: PartialEq<B>,
Rhs: Deref<[B]>,
@ -61,6 +62,7 @@ macro_rules! array_impls {
fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) }
}
#[stable]
impl<'a, A, B, Lhs> PartialEq<[B, ..$N]> for Lhs where
A: PartialEq<B>,
Lhs: Deref<[A]>
@ -71,10 +73,10 @@ macro_rules! array_impls {
fn ne(&self, other: &[B, ..$N]) -> bool { PartialEq::ne(&**self, other[]) }
}
#[unstable = "waiting for Eq to stabilize"]
#[stable]
impl<T:Eq> Eq for [T, ..$N] { }
#[unstable = "waiting for PartialOrd to stabilize"]
#[stable]
impl<T:PartialOrd> PartialOrd for [T, ..$N] {
#[inline]
fn partial_cmp(&self, other: &[T, ..$N]) -> Option<Ordering> {
@ -98,7 +100,7 @@ macro_rules! array_impls {
}
}
#[unstable = "waiting for Ord to stabilize"]
#[stable]
impl<T:Ord> Ord for [T, ..$N] {
#[inline]
fn cmp(&self, other: &[T, ..$N]) -> Ordering {

View File

@ -200,8 +200,10 @@ impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> {
}
}
#[stable]
impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
#[stable]
impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
#[inline]
fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
@ -209,6 +211,7 @@ impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
}
}
#[stable]
impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
B: PartialEq<C> + ToOwned<T>,
C: ToOwned<U>,
@ -219,6 +222,7 @@ impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B
}
}
#[stable]
impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
#[inline]
fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {

View File

@ -224,7 +224,7 @@ impl<T:Default + Copy> Default for Cell<T> {
}
}
#[unstable = "waiting for `PartialEq` trait to become stable"]
#[stable]
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
fn eq(&self, other: &Cell<T>) -> bool {
self.get() == other.get()
@ -358,7 +358,7 @@ impl<T:Default> Default for RefCell<T> {
}
}
#[unstable = "waiting for `PartialEq` to become stable"]
#[stable]
impl<T: PartialEq> PartialEq for RefCell<T> {
fn eq(&self, other: &RefCell<T>) -> bool {
*self.borrow() == *other.borrow()

View File

@ -46,27 +46,37 @@ use self::Ordering::*;
use kinds::Sized;
use option::Option::{mod, Some, None};
/// Trait for values that can be compared for equality and inequality.
/// Trait for equality comparisons which are [partial equivalence relations](
/// http://en.wikipedia.org/wiki/Partial_equivalence_relation).
///
/// This trait allows for partial equality, for types that do not have an
/// This trait allows for partial equality, for types that do not have a full
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
/// so floating point types implement `PartialEq` but not `Eq`.
///
/// Formally, the equality must be (for all `a`, `b` and `c`):
///
/// - symmetric: `a == b` implies `b == a`; and
/// - transitive: `a == b` and `b == c` implies `a == c`.
///
/// Note that these requirements mean that the trait itself must be
/// implemented symmetrically and transitively: if `T: PartialEq<U>`
/// and `U: PartialEq<V>` then `U: PartialEq<T>` and `T:
/// PartialEq<V>`.
///
/// 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`.
#[lang="eq"]
#[unstable = "Definition may change slightly after trait reform"]
#[stable]
pub trait PartialEq<Sized? Rhs = Self> for Sized? {
/// This method tests for `self` and `other` values to be equal, and is used by `==`.
#[stable]
fn eq(&self, other: &Rhs) -> bool;
/// This method tests for `!=`.
#[inline]
#[stable]
fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
}
@ -79,8 +89,8 @@ pub trait PartialEq<Sized? Rhs = Self> for Sized? {
/// - reflexive: `a == a`;
/// - symmetric: `a == b` implies `b == a`; and
/// - transitive: `a == b` and `b == c` implies `a == c`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
#[stable]
pub trait Eq for Sized?: PartialEq<Self> {
// 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
@ -97,12 +107,15 @@ pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
#[deriving(Clone, Copy, PartialEq, Show)]
#[stable]
pub enum Ordering {
/// An ordering where a compared value is less [than another].
Less = -1i,
/// An ordering where a compared value is equal [to another].
Equal = 0i,
/// An ordering where a compared value is greater [than another].
Greater = 1i,
/// An ordering where a compared value is less [than another].
#[stable]
Less = -1i,
/// An ordering where a compared value is equal [to another].
#[stable]
Equal = 0i,
/// An ordering where a compared value is greater [than another].
#[stable]
Greater = 1i,
}
impl Ordering {
@ -126,7 +139,7 @@ impl Ordering {
/// assert!(data == b);
/// ```
#[inline]
#[experimental]
#[stable]
pub fn reverse(self) -> Ordering {
unsafe {
// this compiles really nicely (to a single instruction);
@ -149,8 +162,8 @@ impl Ordering {
/// true; and
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
/// both `==` and `>`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> {
#[stable]
pub trait Ord for Sized?: Eq + PartialOrd<Self> {
/// This method returns an ordering between `self` and `other` values.
///
/// By convention, `self.cmp(&other)` returns the ordering matching
@ -161,23 +174,26 @@ pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> {
/// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5
/// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5
/// ```
fn cmp(&self, other: &Rhs) -> Ordering;
#[stable]
fn cmp(&self, other: &Self) -> Ordering;
}
#[unstable = "Trait is unstable."]
#[stable]
impl Eq for Ordering {}
#[unstable = "Trait is unstable."]
#[stable]
impl Ord for Ordering {
#[inline]
#[stable]
fn cmp(&self, other: &Ordering) -> Ordering {
(*self as int).cmp(&(*other as int))
}
}
#[unstable = "Trait is unstable."]
#[stable]
impl PartialOrd for Ordering {
#[inline]
#[stable]
fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
(*self as int).partial_cmp(&(*other as int))
}
@ -185,6 +201,17 @@ impl PartialOrd for Ordering {
/// Trait for values that can be compared for a sort-order.
///
/// The comparison must satisfy, for all `a`, `b` and `c`:
///
/// - antisymmetry: if `a < b` then `!(a > b)` and vice versa; and
/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for
/// both `==` and `>`.
///
/// Note that these requirements mean that the trait itself must be
/// implemented symmetrically and transitively: if `T: PartialOrd<U>`
/// and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
/// PartialOrd<V>`.
///
/// PartialOrd only requires implementation of the `partial_cmp` method,
/// with the others generated from default implementations.
///
@ -193,14 +220,16 @@ impl PartialOrd for Ordering {
/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
/// 5.11).
#[lang="ord"]
#[unstable = "Definition may change slightly after trait reform"]
#[stable]
pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
/// This method returns an ordering between `self` and `other` values
/// if one exists.
#[stable]
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
#[inline]
#[stable]
fn lt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Less) => true,
@ -210,6 +239,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
/// This method tests less than or equal to (`<=`).
#[inline]
#[stable]
fn le(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Less) | Some(Equal) => true,
@ -219,6 +249,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
/// This method tests greater than (`>`).
#[inline]
#[stable]
fn gt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Greater) => true,
@ -228,6 +259,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
/// This method tests greater than or equal to (`>=`).
#[inline]
#[stable]
fn ge(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Greater) | Some(Equal) => true,
@ -296,7 +328,7 @@ mod impls {
macro_rules! partial_eq_impl {
($($t:ty)*) => ($(
#[unstable = "Trait is unstable."]
#[stable]
impl PartialEq for $t {
#[inline]
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
@ -306,7 +338,7 @@ mod impls {
)*)
}
#[unstable = "Trait is unstable."]
#[stable]
impl PartialEq for () {
#[inline]
fn eq(&self, _other: &()) -> bool { true }
@ -320,7 +352,7 @@ mod impls {
macro_rules! eq_impl {
($($t:ty)*) => ($(
#[unstable = "Trait is unstable."]
#[stable]
impl Eq for $t {}
)*)
}
@ -329,7 +361,7 @@ mod impls {
macro_rules! partial_ord_impl {
($($t:ty)*) => ($(
#[unstable = "Trait is unstable."]
#[stable]
impl PartialOrd for $t {
#[inline]
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
@ -352,7 +384,7 @@ mod impls {
)*)
}
#[unstable = "Trait is unstable."]
#[stable]
impl PartialOrd for () {
#[inline]
fn partial_cmp(&self, _: &()) -> Option<Ordering> {
@ -360,7 +392,7 @@ mod impls {
}
}
#[unstable = "Trait is unstable."]
#[stable]
impl PartialOrd for bool {
#[inline]
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
@ -372,7 +404,7 @@ mod impls {
macro_rules! ord_impl {
($($t:ty)*) => ($(
#[unstable = "Trait is unstable."]
#[stable]
impl Ord for $t {
#[inline]
fn cmp(&self, other: &$t) -> Ordering {
@ -384,13 +416,13 @@ mod impls {
)*)
}
#[unstable = "Trait is unstable."]
#[stable]
impl Ord for () {
#[inline]
fn cmp(&self, _other: &()) -> Ordering { Equal }
}
#[unstable = "Trait is unstable."]
#[stable]
impl Ord for bool {
#[inline]
fn cmp(&self, other: &bool) -> Ordering {
@ -402,68 +434,69 @@ mod impls {
// & pointers
#[unstable = "Trait is unstable."]
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T {
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: Ord> Ord for &'a T {
#[stable]
impl<'a, Sized? A> Ord for &'a A where A: Ord {
#[inline]
fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) }
fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: Eq> Eq for &'a T {}
#[stable]
impl<'a, Sized? A> Eq for &'a A where A: Eq {}
// &mut pointers
#[unstable = "Trait is unstable."]
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T {
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: Ord> Ord for &'a mut T {
#[stable]
impl<'a, Sized? A> Ord for &'a mut A where A: Ord {
#[inline]
fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) }
fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: Eq> Eq for &'a mut T {}
#[stable]
impl<'a, Sized? A> Eq for &'a mut A where A: Eq {}
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
@ -471,6 +504,7 @@ mod impls {
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable]
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }

View File

@ -379,6 +379,7 @@ impl<T> MutPtrExt<T> for *mut T {
}
// Equality for pointers
#[stable]
impl<T> PartialEq for *const T {
#[inline]
fn eq(&self, other: &*const T) -> bool {
@ -388,8 +389,10 @@ impl<T> PartialEq for *const T {
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
}
#[stable]
impl<T> Eq for *const T {}
#[stable]
impl<T> PartialEq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
@ -399,6 +402,7 @@ impl<T> PartialEq for *mut T {
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}
#[stable]
impl<T> Eq for *mut T {}
// Equivalence for pointers
@ -439,6 +443,7 @@ mod externfnpointers {
use mem;
use cmp::PartialEq;
#[stable]
impl<_R> PartialEq for extern "C" fn() -> _R {
#[inline]
fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
@ -449,6 +454,7 @@ mod externfnpointers {
}
macro_rules! fnptreq {
($($p:ident),*) => {
#[stable]
impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
#[inline]
fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
@ -468,6 +474,7 @@ mod externfnpointers {
}
// Comparison for pointers
#[stable]
impl<T> Ord for *const T {
#[inline]
fn cmp(&self, other: &*const T) -> Ordering {
@ -481,6 +488,7 @@ impl<T> Ord for *const T {
}
}
#[stable]
impl<T> PartialOrd for *const T {
#[inline]
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
@ -500,6 +508,7 @@ impl<T> PartialOrd for *const T {
fn ge(&self, other: &*const T) -> bool { *self >= *other }
}
#[stable]
impl<T> Ord for *mut T {
#[inline]
fn cmp(&self, other: &*mut T) -> Ordering {
@ -513,6 +522,7 @@ impl<T> Ord for *mut T {
}
}
#[stable]
impl<T> PartialOrd for *mut T {
#[inline]
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {

View File

@ -1437,7 +1437,7 @@ pub mod bytes {
// Boilerplate traits
//
#[unstable = "waiting for DST"]
#[stable]
impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
fn eq(&self, other: &[B]) -> bool {
self.len() == other.len() &&
@ -1449,7 +1449,7 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
}
}
#[unstable = "waiting for DST"]
#[stable]
impl<T: Eq> Eq for [T] {}
#[allow(deprecated)]
@ -1466,14 +1466,14 @@ impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[unstable = "waiting for DST"]
#[stable]
impl<T: Ord> Ord for [T] {
fn cmp(&self, other: &[T]) -> Ordering {
order::cmp(self.iter(), other.iter())
}
}
#[unstable = "waiting for DST"]
#[stable]
impl<T: PartialOrd> PartialOrd for [T] {
#[inline]
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {

View File

@ -1143,6 +1143,7 @@ pub mod traits {
use ops;
use str::{Str, StrExt, eq_slice};
#[stable]
impl Ord for str {
#[inline]
fn cmp(&self, other: &str) -> Ordering {
@ -1158,6 +1159,7 @@ pub mod traits {
}
}
#[stable]
impl PartialEq for str {
#[inline]
fn eq(&self, other: &str) -> bool {
@ -1167,8 +1169,10 @@ pub mod traits {
fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
}
#[stable]
impl Eq for str {}
#[stable]
impl PartialOrd for str {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {

View File

@ -132,7 +132,7 @@ macro_rules! tuple_impls {
}
}
#[unstable = "waiting for PartialEq to stabilize"]
#[stable]
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
#[inline]
fn eq(&self, other: &($($T,)+)) -> bool {
@ -144,10 +144,10 @@ macro_rules! tuple_impls {
}
}
#[unstable = "waiting for Eq to stabilize"]
#[stable]
impl<$($T:Eq),+> Eq for ($($T,)+) {}
#[unstable = "waiting for PartialOrd to stabilize"]
#[stable]
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
#[inline]
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
@ -171,7 +171,7 @@ macro_rules! tuple_impls {
}
}
#[unstable = "waiting for Ord to stabilize"]
#[stable]
impl<$($T:Ord),+> Ord for ($($T,)+) {
#[inline]
fn cmp(&self, other: &($($T,)+)) -> Ordering {

View File

@ -1261,6 +1261,7 @@ impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
}
}
#[stable]
impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
fn eq(&self, other: &HashMap<K, V, H>) -> bool {
if self.len() != other.len() { return false; }
@ -1271,6 +1272,7 @@ impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V,
}
}
#[stable]
impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {

View File

@ -572,6 +572,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
}
}
#[stable]
impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
fn eq(&self, other: &HashSet<T, H>) -> bool {
if self.len() != other.len() { return false; }
@ -580,6 +581,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
}
}
#[stable]
impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {