From b94bcbf56eab163517e8ffc93888284b8dbb6238 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 30 Dec 2014 14:44:26 -0800 Subject: [PATCH] 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] --- src/liballoc/arc.rs | 8 +- src/liballoc/boxed.rs | 6 +- src/liballoc/rc.rs | 8 +- src/libcollections/bit.rs | 8 ++ src/libcollections/btree/map.rs | 4 + src/libcollections/dlist.rs | 4 + src/libcollections/ring_buf.rs | 4 + src/libcollections/string.rs | 5 + src/libcollections/vec.rs | 13 ++- src/libcollections/vec_map.rs | 5 + src/libcore/array.rs | 10 +- src/libcore/borrow.rs | 4 + src/libcore/cell.rs | 4 +- src/libcore/cmp.rs | 148 ++++++++++++++++++----------- src/libcore/ptr.rs | 10 ++ src/libcore/slice.rs | 8 +- src/libcore/str/mod.rs | 4 + src/libcore/tuple.rs | 8 +- src/libstd/collections/hash/map.rs | 2 + src/libstd/collections/hash/set.rs | 2 + 20 files changed, 182 insertions(+), 83 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 21c47cdf3d752..f6f83f22f9240 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -458,7 +458,7 @@ impl Drop for Weak { } } -#[unstable = "waiting on PartialEq"] +#[stable] impl PartialEq for Arc { /// Equality for two `Arc`s. /// @@ -490,7 +490,7 @@ impl PartialEq for Arc { /// ``` fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) } } -#[unstable = "waiting on PartialOrd"] +#[stable] impl PartialOrd for Arc { /// Partial comparison for two `Arc`s. /// @@ -569,11 +569,11 @@ impl PartialOrd for Arc { /// ``` fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } } -#[unstable = "waiting on Ord"] +#[stable] impl Ord for Arc { fn cmp(&self, other: &Arc) -> Ordering { (**self).cmp(&**other) } } -#[unstable = "waiting on Eq"] +#[stable] impl Eq for Arc {} impl fmt::Show for Arc { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 3c6b2d2cbc068..74f0599e486e1 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -72,12 +72,14 @@ impl Clone for Box { } } +#[stable] impl PartialEq for Box { #[inline] fn eq(&self, other: &Box) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &Box) -> bool { PartialEq::ne(&**self, &**other) } } +#[stable] impl PartialOrd for Box { #[inline] fn partial_cmp(&self, other: &Box) -> Option { @@ -92,12 +94,14 @@ impl PartialOrd for Box { #[inline] fn gt(&self, other: &Box) -> bool { PartialOrd::gt(&**self, &**other) } } +#[stable] impl Ord for Box { #[inline] fn cmp(&self, other: &Box) -> Ordering { Ord::cmp(&**self, &**other) } -} + +#[stable]} impl Eq for Box {} impl> Hash for Box { diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 214fae02ce272..75d4342083b98 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -452,7 +452,7 @@ impl Default for Rc { } } -#[unstable = "PartialEq is unstable."] +#[stable] impl PartialEq for Rc { /// Equality for two `Rc`s. /// @@ -487,10 +487,10 @@ impl PartialEq for Rc { fn ne(&self, other: &Rc) -> bool { **self != **other } } -#[unstable = "Eq is unstable."] +#[stable] impl Eq for Rc {} -#[unstable = "PartialOrd is unstable."] +#[stable] impl PartialOrd for Rc { /// Partial comparison for two `Rc`s. /// @@ -575,7 +575,7 @@ impl PartialOrd for Rc { fn ge(&self, other: &Rc) -> bool { **self >= **other } } -#[unstable = "Ord is unstable."] +#[stable] impl Ord for Rc { /// Comparison for two `Rc`s. /// diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 430d7210bf69b..08d12151efd3d 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -965,6 +965,7 @@ impl Clone for Bitv { } } +#[stable] impl PartialOrd for Bitv { #[inline] fn partial_cmp(&self, other: &Bitv) -> Option { @@ -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 hash::Hash 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 for BitvSet { } } +#[stable] impl PartialOrd for BitvSet { #[inline] fn partial_cmp(&self, other: &BitvSet) -> Option { @@ -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 { diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 65c644da3d892..a3dff3e870658 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -843,6 +843,7 @@ impl Default for BTreeMap { } } +#[stable] impl PartialEq for BTreeMap { fn eq(&self, other: &BTreeMap) -> bool { self.len() == other.len() && @@ -850,8 +851,10 @@ impl PartialEq for BTreeMap { } } +#[stable] impl Eq for BTreeMap {} +#[stable] impl PartialOrd for BTreeMap { #[inline] fn partial_cmp(&self, other: &BTreeMap) -> Option { @@ -859,6 +862,7 @@ impl PartialOrd for BTreeMap { } } +#[stable] impl Ord for BTreeMap { #[inline] fn cmp(&self, other: &BTreeMap) -> Ordering { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index d8ce79f4fe90d..9f2dcda92c025 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -770,6 +770,7 @@ impl Extend for DList { } } +#[stable] impl PartialEq for DList { fn eq(&self, other: &DList) -> bool { self.len() == other.len() && @@ -782,14 +783,17 @@ impl PartialEq for DList { } } +#[stable] impl Eq for DList {} +#[stable] impl PartialOrd for DList { fn partial_cmp(&self, other: &DList) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } +#[stable] impl Ord for DList { #[inline] fn cmp(&self, other: &DList) -> Ordering { diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index df8e08f07a321..c8d21761ac088 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -1290,6 +1290,7 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} +#[stable] impl PartialEq for RingBuf { fn eq(&self, other: &RingBuf) -> bool { self.len() == other.len() && @@ -1297,14 +1298,17 @@ impl PartialEq for RingBuf { } } +#[stable] impl Eq for RingBuf {} +#[stable] impl PartialOrd for RingBuf { fn partial_cmp(&self, other: &RingBuf) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } +#[stable] impl Ord for RingBuf { #[inline] fn cmp(&self, other: &RingBuf) -> Ordering { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index c6c19cae75f1e..0969f0fcfcc47 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -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> for &'b str { #[inline] fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bf69980b49c8f..e2a9d2f8f63c6 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -588,6 +588,7 @@ impl Extend for Vec { } } +#[stable] impl PartialEq> for Vec where A: PartialEq { #[inline] fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } @@ -597,6 +598,7 @@ impl PartialEq> for Vec where A: PartialEq { macro_rules! impl_eq { ($lhs:ty, $rhs:ty) => { + #[stable] impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq { #[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 { #[inline] fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) } @@ -616,6 +619,7 @@ macro_rules! impl_eq { impl_eq! { Vec, &'b [B] } impl_eq! { Vec, &'b mut [B] } +#[stable] impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone { #[inline] fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } @@ -623,6 +627,7 @@ impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } } +#[stable] impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { #[inline] fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } @@ -632,6 +637,7 @@ impl<'a, A, B> PartialEq> for Vec 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 + 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> for $rhs where A: Clone, B: PartialEq { #[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 PartialOrd for Vec { #[inline] fn partial_cmp(&self, other: &Vec) -> Option { @@ -659,7 +666,7 @@ impl PartialOrd for Vec { } } -#[unstable = "waiting on Eq stability"] +#[stable] impl Eq for Vec {} #[allow(deprecated)] @@ -669,7 +676,7 @@ impl> Equiv for Vec { fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } -#[unstable = "waiting on Ord stability"] +#[stable] impl Ord for Vec { #[inline] fn cmp(&self, other: &Vec) -> Ordering { diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 5ebcc736624f6..750f1458a4242 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -537,14 +537,18 @@ impl VecMap { } } + +#[stable] impl PartialEq for VecMap { fn eq(&self, other: &VecMap) -> bool { iter::order::eq(self.iter(), other.iter()) } } +#[stable] impl Eq for VecMap {} +#[stable] impl PartialOrd for VecMap { #[inline] fn partial_cmp(&self, other: &VecMap) -> Option { @@ -552,6 +556,7 @@ impl PartialOrd for VecMap { } } +#[stable] impl Ord for VecMap { #[inline] fn cmp(&self, other: &VecMap) -> Ordering { diff --git a/src/libcore/array.rs b/src/libcore/array.rs index e85a132ed363f..88e23377046f1 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -39,7 +39,7 @@ macro_rules! array_impls { } } - #[unstable = "waiting for PartialEq to stabilize"] + #[stable] impl PartialEq<[B, ..$N]> for [A, ..$N] where A: PartialEq { #[inline] fn eq(&self, other: &[B, ..$N]) -> bool { @@ -51,6 +51,7 @@ macro_rules! array_impls { } } + #[stable] impl<'a, A, B, Rhs> PartialEq for [A, ..$N] where A: PartialEq, 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, 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 Eq for [T, ..$N] { } - #[unstable = "waiting for PartialOrd to stabilize"] + #[stable] impl PartialOrd for [T, ..$N] { #[inline] fn partial_cmp(&self, other: &[T, ..$N]) -> Option { @@ -98,7 +100,7 @@ macro_rules! array_impls { } } - #[unstable = "waiting for Ord to stabilize"] + #[stable] impl Ord for [T, ..$N] { #[inline] fn cmp(&self, other: &[T, ..$N]) -> Ordering { diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 9bbcf67773ebb..3a2cb8ea7d984 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -200,8 +200,10 @@ impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned { } } +#[stable] impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned {} +#[stable] impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned { #[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 { } } +#[stable] impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq> for Cow<'a, T, B> where B: PartialEq + ToOwned, C: ToOwned, @@ -219,6 +222,7 @@ impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq> for Cow<'a, T, B } } +#[stable] impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned { #[inline] fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option { diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 01a1e7f97110a..6249f7600cd22 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -224,7 +224,7 @@ impl Default for Cell { } } -#[unstable = "waiting for `PartialEq` trait to become stable"] +#[stable] impl PartialEq for Cell { fn eq(&self, other: &Cell) -> bool { self.get() == other.get() @@ -358,7 +358,7 @@ impl Default for RefCell { } } -#[unstable = "waiting for `PartialEq` to become stable"] +#[stable] impl PartialEq for RefCell { fn eq(&self, other: &RefCell) -> bool { *self.borrow() == *other.borrow() diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index ca523db214b0c..367c794e84bb6 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -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` +/// and `U: PartialEq` then `U: PartialEq` and `T: +/// PartialEq`. +/// /// 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 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 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 for Sized?: PartialEq { +#[stable] +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 @@ -97,12 +107,15 @@ pub trait Eq for Sized?: PartialEq { #[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 for Sized?: Eq + PartialOrd { +#[stable] +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 @@ -161,23 +174,26 @@ pub trait Ord for Sized?: Eq + PartialOrd { /// 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 { (*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` +/// and `U: PartialOrd` then `U: PartialOrd` and `T: +/// PartialOrd`. +/// /// 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 for Sized?: PartialEq { /// This method returns an ordering between `self` and `other` values /// if one exists. + #[stable] fn partial_cmp(&self, other: &Rhs) -> Option; /// 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 for Sized?: PartialEq { /// 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 for Sized?: PartialEq { /// 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 for Sized?: PartialEq { /// 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 { @@ -352,7 +384,7 @@ mod impls { )*) } - #[unstable = "Trait is unstable."] + #[stable] impl PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option { @@ -360,7 +392,7 @@ mod impls { } } - #[unstable = "Trait is unstable."] + #[stable] impl PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option { @@ -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 { #[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 { #[inline] - fn partial_cmp(&self, other: &&'a T) -> Option { + fn partial_cmp(&self, other: &&'b B) -> Option { 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 { #[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 { #[inline] - fn partial_cmp(&self, other: &&'a mut T) -> Option { + fn partial_cmp(&self, other: &&'b mut B) -> Option { 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 { #[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 { #[inline] fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 75bb8d33ea85f..faf1d781465c7 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -379,6 +379,7 @@ impl MutPtrExt for *mut T { } // Equality for pointers +#[stable] impl PartialEq for *const T { #[inline] fn eq(&self, other: &*const T) -> bool { @@ -388,8 +389,10 @@ impl PartialEq for *const T { fn ne(&self, other: &*const T) -> bool { !self.eq(other) } } +#[stable] impl Eq for *const T {} +#[stable] impl PartialEq for *mut T { #[inline] fn eq(&self, other: &*mut T) -> bool { @@ -399,6 +402,7 @@ impl PartialEq for *mut T { fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } } +#[stable] impl 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 Ord for *const T { #[inline] fn cmp(&self, other: &*const T) -> Ordering { @@ -481,6 +488,7 @@ impl Ord for *const T { } } +#[stable] impl PartialOrd for *const T { #[inline] fn partial_cmp(&self, other: &*const T) -> Option { @@ -500,6 +508,7 @@ impl PartialOrd for *const T { fn ge(&self, other: &*const T) -> bool { *self >= *other } } +#[stable] impl Ord for *mut T { #[inline] fn cmp(&self, other: &*mut T) -> Ordering { @@ -513,6 +522,7 @@ impl Ord for *mut T { } } +#[stable] impl PartialOrd for *mut T { #[inline] fn partial_cmp(&self, other: &*mut T) -> Option { diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index f356a0867d252..77bb5cc2499c8 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1437,7 +1437,7 @@ pub mod bytes { // Boilerplate traits // -#[unstable = "waiting for DST"] +#[stable] impl PartialEq<[B]> for [A] where A: PartialEq { fn eq(&self, other: &[B]) -> bool { self.len() == other.len() && @@ -1449,7 +1449,7 @@ impl PartialEq<[B]> for [A] where A: PartialEq { } } -#[unstable = "waiting for DST"] +#[stable] impl Eq for [T] {} #[allow(deprecated)] @@ -1466,14 +1466,14 @@ impl<'a,T:PartialEq, Sized? V: AsSlice> Equiv for &'a mut [T] { fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } -#[unstable = "waiting for DST"] +#[stable] impl Ord for [T] { fn cmp(&self, other: &[T]) -> Ordering { order::cmp(self.iter(), other.iter()) } } -#[unstable = "waiting for DST"] +#[stable] impl PartialOrd for [T] { #[inline] fn partial_cmp(&self, other: &[T]) -> Option { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8db672b265375..59cf79408b100 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -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 { diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index a92914c99e35b..576989fabe77c 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -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 { @@ -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 { diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 7b7473b2c993c..b473a665c76b1 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1261,6 +1261,7 @@ impl, V: Clone, S, H: Hasher> HashMap { } } +#[stable] impl, V: PartialEq, S, H: Hasher> PartialEq for HashMap { fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } @@ -1271,6 +1272,7 @@ impl, V: PartialEq, S, H: Hasher> PartialEq for HashMap, V: Eq, S, H: Hasher> Eq for HashMap {} impl + Show, V: Show, S, H: Hasher> Show for HashMap { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 6d83d5510b357..93f6895f6885b 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -572,6 +572,7 @@ impl, S, H: Hasher> HashSet { } } +#[stable] impl, S, H: Hasher> PartialEq for HashSet { fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { return false; } @@ -580,6 +581,7 @@ impl, S, H: Hasher> PartialEq for HashSet { } } +#[stable] impl, S, H: Hasher> Eq for HashSet {} impl + fmt::Show, S, H: Hasher> fmt::Show for HashSet {