Skip to content

Commit

Permalink
Stabilize cmp
Browse files Browse the repository at this point in the history
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](rust-lang/rfcs#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]
  • Loading branch information
aturon committed Dec 30, 2014
1 parent 84f5ad8 commit b94bcbf
Show file tree
Hide file tree
Showing 20 changed files with 182 additions and 83 deletions.
8 changes: 4 additions & 4 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -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> {
Expand Down
6 changes: 5 additions & 1 deletion src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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> {
Expand Down
8 changes: 4 additions & 4 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
///
Expand Down
8 changes: 8 additions & 0 deletions src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,13 +965,15 @@ impl Clone for Bitv {
}
}

#[stable]
impl PartialOrd for Bitv {
#[inline]
fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}

#[stable]
impl Ord for Bitv {
#[inline]
fn cmp(&self, other: &Bitv) -> Ordering {
Expand All @@ -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 {
Expand All @@ -1007,6 +1010,7 @@ impl cmp::PartialEq for Bitv {
}
}

#[stable]
impl cmp::Eq for Bitv {}

/// An iterator for `Bitv`.
Expand Down Expand Up @@ -1129,6 +1133,7 @@ impl Extend<uint> for BitvSet {
}
}

#[stable]
impl PartialOrd for BitvSet {
#[inline]
fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
Expand All @@ -1137,6 +1142,7 @@ impl PartialOrd for BitvSet {
}
}

#[stable]
impl Ord for BitvSet {
#[inline]
fn cmp(&self, other: &BitvSet) -> Ordering {
Expand All @@ -1145,6 +1151,7 @@ impl Ord for BitvSet {
}
}

#[stable]
impl cmp::PartialEq for BitvSet {
#[inline]
fn eq(&self, other: &BitvSet) -> bool {
Expand All @@ -1153,6 +1160,7 @@ impl cmp::PartialEq for BitvSet {
}
}

#[stable]
impl cmp::Eq for BitvSet {}

impl BitvSet {
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,22 +843,26 @@ 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() &&
self.iter().zip(other.iter()).all(|(a, b)| a == b)
}
}

#[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> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}

#[stable]
impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
#[inline]
fn cmp(&self, other: &BTreeMap<K, V>) -> Ordering {
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() &&
Expand All @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/ring_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,21 +1290,25 @@ 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() &&
self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
}
}

#[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 {
Expand Down
5 changes: 5 additions & 0 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand All @@ -824,13 +825,15 @@ 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) }
#[inline]
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) }
Expand All @@ -844,13 +847,15 @@ 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) }
#[inline]
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) }
Expand Down
13 changes: 10 additions & 3 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand All @@ -597,13 +598,15 @@ 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) }
#[inline]
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) }
Expand All @@ -616,13 +619,15 @@ 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) }
#[inline]
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) }
Expand All @@ -632,13 +637,15 @@ 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) }
#[inline]
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) }
Expand All @@ -651,15 +658,15 @@ 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> {
self.as_slice().partial_cmp(other.as_slice())
}
}

#[unstable = "waiting on Eq stability"]
#[stable]
impl<T: Eq> Eq for Vec<T> {}

#[allow(deprecated)]
Expand All @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions src/libcollections/vec_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,21 +537,26 @@ 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> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}

#[stable]
impl<V: Ord> Ord for VecMap<V> {
#[inline]
fn cmp(&self, other: &VecMap<V>) -> Ordering {
Expand Down
Loading

2 comments on commit b94bcbf

@aturon
Copy link
Owner Author

@aturon aturon commented on b94bcbf Dec 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=alexcrichton

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

Please sign in to comment.