Skip to content

Commit 4d7d101

Browse files
committed
create a sensible comparison trait hierarchy
* `Ord` inherits from `Eq` * `TotalOrd` inherits from `TotalEq` * `TotalOrd` inherits from `Ord` * `TotalEq` inherits from `Eq` This is a partial implementation of #12517.
1 parent 33768c4 commit 4d7d101

29 files changed

+156
-53
lines changed

src/libcollections/btree.rs

+71
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for BTree<K, V> {
9292
}
9393
}
9494

95+
impl<K: TotalOrd, V: TotalEq> Eq for BTree<K, V> {
96+
fn eq(&self, other: &BTree<K, V>) -> bool {
97+
self.equals(other)
98+
}
99+
}
95100

96101
impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
97102
///Testing equality on BTrees by comparing the root.
@@ -100,6 +105,12 @@ impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
100105
}
101106
}
102107

108+
impl<K: TotalOrd, V: TotalEq> Ord for BTree<K, V> {
109+
fn lt(&self, other: &BTree<K, V>) -> bool {
110+
self.cmp(other) == Less
111+
}
112+
}
113+
103114
impl<K: TotalOrd, V: TotalEq> TotalOrd for BTree<K, V> {
104115
///Returns an ordering based on the root nodes of each BTree.
105116
fn cmp(&self, other: &BTree<K, V>) -> Ordering {
@@ -191,6 +202,12 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V> {
191202
}
192203
}
193204

205+
impl<K: TotalOrd, V: TotalEq> Eq for Node<K, V> {
206+
fn eq(&self, other: &Node<K, V>) -> bool {
207+
self.equals(other)
208+
}
209+
}
210+
194211
impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
195212
///Returns whether two nodes are equal based on the keys of each element.
196213
///Two nodes are equal if all of their keys are the same.
@@ -215,6 +232,12 @@ impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
215232
}
216233
}
217234

235+
impl<K: TotalOrd, V: TotalEq> Ord for Node<K, V> {
236+
fn lt(&self, other: &Node<K, V>) -> bool {
237+
self.cmp(other) == Less
238+
}
239+
}
240+
218241
impl<K: TotalOrd, V: TotalEq> TotalOrd for Node<K, V> {
219242
///Implementation of TotalOrd for Nodes.
220243
fn cmp(&self, other: &Node<K, V>) -> Ordering {
@@ -380,13 +403,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Leaf<K, V> {
380403
}
381404
}
382405

406+
impl<K: TotalOrd, V: TotalEq> Eq for Leaf<K, V> {
407+
fn eq(&self, other: &Leaf<K, V>) -> bool {
408+
self.equals(other)
409+
}
410+
}
411+
383412
impl<K: TotalOrd, V: TotalEq> TotalEq for Leaf<K, V> {
384413
///Implementation of equals function for leaves that compares LeafElts.
385414
fn equals(&self, other: &Leaf<K, V>) -> bool {
386415
self.elts.equals(&other.elts)
387416
}
388417
}
389418

419+
impl<K: TotalOrd, V: TotalEq> Ord for Leaf<K, V> {
420+
fn lt(&self, other: &Leaf<K, V>) -> bool {
421+
self.cmp(other) == Less
422+
}
423+
}
424+
390425
impl<K: TotalOrd, V: TotalEq> TotalOrd for Leaf<K, V> {
391426
///Returns an ordering based on the first element of each Leaf.
392427
fn cmp(&self, other: &Leaf<K, V>) -> Ordering {
@@ -602,13 +637,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Branch<K, V> {
602637
}
603638
}
604639

640+
impl<K: TotalOrd, V: TotalEq> Eq for Branch<K, V> {
641+
fn eq(&self, other: &Branch<K, V>) -> bool {
642+
self.equals(other)
643+
}
644+
}
645+
605646
impl<K: TotalOrd, V: TotalEq> TotalEq for Branch<K, V> {
606647
///Equals function for Branches--compares all the elements in each branch
607648
fn equals(&self, other: &Branch<K, V>) -> bool {
608649
self.elts.equals(&other.elts)
609650
}
610651
}
611652

653+
impl<K: TotalOrd, V: TotalEq> Ord for Branch<K, V> {
654+
fn lt(&self, other: &Branch<K, V>) -> bool {
655+
self.cmp(other) == Less
656+
}
657+
}
658+
612659
impl<K: TotalOrd, V: TotalEq> TotalOrd for Branch<K, V> {
613660
///Compares the first elements of two branches to determine an ordering
614661
fn cmp(&self, other: &Branch<K, V>) -> Ordering {
@@ -663,13 +710,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V> {
663710
}
664711
}
665712

713+
impl<K: TotalOrd, V: TotalEq> Eq for LeafElt<K, V> {
714+
fn eq(&self, other: &LeafElt<K, V>) -> bool {
715+
self.equals(other)
716+
}
717+
}
718+
666719
impl<K: TotalOrd, V: TotalEq> TotalEq for LeafElt<K, V> {
667720
///TotalEq for LeafElts
668721
fn equals(&self, other: &LeafElt<K, V>) -> bool {
669722
self.key.equals(&other.key) && self.value.equals(&other.value)
670723
}
671724
}
672725

726+
impl<K: TotalOrd, V: TotalEq> Ord for LeafElt<K, V> {
727+
fn lt(&self, other: &LeafElt<K, V>) -> bool {
728+
self.cmp(other) == Less
729+
}
730+
}
731+
673732
impl<K: TotalOrd, V: TotalEq> TotalOrd for LeafElt<K, V> {
674733
///Returns an ordering based on the keys of the LeafElts.
675734
fn cmp(&self, other: &LeafElt<K, V>) -> Ordering {
@@ -705,13 +764,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V> {
705764
}
706765
}
707766

767+
impl<K: TotalOrd, V: TotalEq> Eq for BranchElt<K, V>{
768+
fn eq(&self, other: &BranchElt<K, V>) -> bool {
769+
self.equals(other)
770+
}
771+
}
772+
708773
impl<K: TotalOrd, V: TotalEq> TotalEq for BranchElt<K, V>{
709774
///TotalEq for BranchElts
710775
fn equals(&self, other: &BranchElt<K, V>) -> bool {
711776
self.key.equals(&other.key)&&self.value.equals(&other.value)
712777
}
713778
}
714779

780+
impl<K: TotalOrd, V: TotalEq> Ord for BranchElt<K, V> {
781+
fn lt(&self, other: &BranchElt<K, V>) -> bool {
782+
self.cmp(other) == Less
783+
}
784+
}
785+
715786
impl<K: TotalOrd, V: TotalEq> TotalOrd for BranchElt<K, V> {
716787
///Fulfills TotalOrd for BranchElts
717788
fn cmp(&self, other: &BranchElt<K, V>) -> Ordering {

src/libcollections/dlist.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ impl<A: Eq> Eq for DList<A> {
607607
}
608608
}
609609

610-
impl<A: Eq + Ord> Ord for DList<A> {
610+
impl<A: Ord> Ord for DList<A> {
611611
fn lt(&self, other: &DList<A>) -> bool {
612612
iter::order::lt(self.iter(), other.iter())
613613
}

src/libextra/workcache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ use std::io::{File, MemWriter};
8888
*
8989
*/
9090

91-
#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
91+
#[deriving(Clone, Eq, Encodable, Decodable, Ord, TotalOrd, TotalEq)]
9292
struct WorkKey {
9393
kind: ~str,
9494
name: ~str

src/librustc/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use syntax::attr::AttrMetaMethods;
4646
use syntax::crateid::CrateId;
4747
use syntax::parse::token;
4848

49-
#[deriving(Clone, Eq, TotalOrd, TotalEq)]
49+
#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
5050
pub enum OutputType {
5151
OutputTypeBitcode,
5252
OutputTypeAssembly,

src/librustc/driver/session.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub enum EntryFnType {
166166
EntryNone,
167167
}
168168

169-
#[deriving(Eq, Clone, TotalOrd, TotalEq)]
169+
#[deriving(Eq, Ord, Clone, TotalOrd, TotalEq)]
170170
pub enum CrateType {
171171
CrateTypeExecutable,
172172
CrateTypeDylib,

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
525525
}
526526
}
527527

528-
fn compare_vals<T : Eq + Ord>(a: T, b: T) -> Option<int> {
528+
fn compare_vals<T: Ord>(a: T, b: T) -> Option<int> {
529529
Some(if a == b { 0 } else if a < b { -1 } else { 1 })
530530
}
531531
pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> {

src/librustc/middle/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -633,13 +633,13 @@ impl Region {
633633
}
634634
}
635635

636-
#[deriving(Clone, Eq, TotalOrd, TotalEq, Hash, Encodable, Decodable, Show)]
636+
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
637637
pub struct FreeRegion {
638638
scope_id: NodeId,
639639
bound_region: BoundRegion
640640
}
641641

642-
#[deriving(Clone, Eq, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
642+
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
643643
pub enum BoundRegion {
644644
/// An anonymous region parameter for a given fn (&T)
645645
BrAnon(uint),

src/libstd/cmp.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ pub trait Eq {
4242
}
4343

4444
/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
45-
pub trait TotalEq {
46-
fn equals(&self, other: &Self) -> bool;
45+
pub trait TotalEq: Eq {
46+
/// This method must return the same value as `eq`. It exists to prevent
47+
/// deriving `TotalEq` from fields not implementing the `TotalEq` trait.
48+
fn equals(&self, other: &Self) -> bool {
49+
self.eq(other)
50+
}
4751
}
4852

4953
macro_rules! totaleq_impl(
@@ -76,7 +80,7 @@ totaleq_impl!(char)
7680
pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }
7781

7882
/// Trait for types that form a total order
79-
pub trait TotalOrd: TotalEq {
83+
pub trait TotalOrd: TotalEq + Ord {
8084
fn cmp(&self, other: &Self) -> Ordering;
8185
}
8286

@@ -161,16 +165,14 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
161165
* (cf. IEEE 754-2008 section 5.11).
162166
*/
163167
#[lang="ord"]
164-
pub trait Ord {
168+
pub trait Ord: Eq {
165169
fn lt(&self, other: &Self) -> bool;
166170
#[inline]
167171
fn le(&self, other: &Self) -> bool { !other.lt(self) }
168172
#[inline]
169173
fn gt(&self, other: &Self) -> bool { other.lt(self) }
170174
#[inline]
171175
fn ge(&self, other: &Self) -> bool { !self.lt(other) }
172-
173-
// FIXME (#12068): Add min/max/clamp default methods
174176
}
175177

176178
/// The equivalence relation. Two values may be equivalent even if they are

src/libstd/iter.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -2033,7 +2033,7 @@ pub fn range_inclusive<A: Add<A, A> + Ord + Clone + One + ToPrimitive>(start: A,
20332033
RangeInclusive{range: range(start, stop), done: false}
20342034
}
20352035

2036-
impl<A: Add<A, A> + Eq + Ord + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> {
2036+
impl<A: Add<A, A> + Ord + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> {
20372037
#[inline]
20382038
fn next(&mut self) -> Option<A> {
20392039
match self.range.next() {
@@ -2244,7 +2244,7 @@ pub mod order {
22442244
}
22452245

22462246
/// Return `a` < `b` lexicographically (Using partial order, `Ord`)
2247-
pub fn lt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
2247+
pub fn lt<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
22482248
loop {
22492249
match (a.next(), b.next()) {
22502250
(None, None) => return false,
@@ -2256,7 +2256,7 @@ pub mod order {
22562256
}
22572257

22582258
/// Return `a` <= `b` lexicographically (Using partial order, `Ord`)
2259-
pub fn le<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
2259+
pub fn le<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
22602260
loop {
22612261
match (a.next(), b.next()) {
22622262
(None, None) => return true,
@@ -2268,7 +2268,7 @@ pub mod order {
22682268
}
22692269

22702270
/// Return `a` > `b` lexicographically (Using partial order, `Ord`)
2271-
pub fn gt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
2271+
pub fn gt<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
22722272
loop {
22732273
match (a.next(), b.next()) {
22742274
(None, None) => return false,
@@ -2280,7 +2280,7 @@ pub mod order {
22802280
}
22812281

22822282
/// Return `a` >= `b` lexicographically (Using partial order, `Ord`)
2283-
pub fn ge<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
2283+
pub fn ge<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
22842284
loop {
22852285
match (a.next(), b.next()) {
22862286
(None, None) => return true,
@@ -2978,6 +2978,12 @@ mod tests {
29782978
}
29792979
}
29802980

2981+
impl Eq for Foo {
2982+
fn eq(&self, _: &Foo) -> bool {
2983+
true
2984+
}
2985+
}
2986+
29812987
impl Ord for Foo {
29822988
fn lt(&self, _: &Foo) -> bool {
29832989
false

src/libstd/option.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
use any::Any;
4141
use clone::Clone;
4242
use clone::DeepClone;
43-
use cmp::{Eq, TotalEq, TotalOrd};
43+
use cmp::{Eq, TotalOrd};
4444
use default::Default;
4545
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
4646
use kinds::Send;

src/libstd/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ pub mod traits {
682682
fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
683683
}
684684

685-
impl<'a, T: Eq + Ord> Ord for &'a [T] {
685+
impl<'a, T: Ord> Ord for &'a [T] {
686686
fn lt(&self, other: & &'a [T]) -> bool {
687687
order::lt(self.iter(), other.iter())
688688
}
@@ -700,7 +700,7 @@ pub mod traits {
700700
}
701701
}
702702

703-
impl<T: Eq + Ord> Ord for ~[T] {
703+
impl<T: Ord> Ord for ~[T] {
704704
#[inline]
705705
fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
706706
#[inline]

src/libstd/vec_ng.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use cast::{forget, transmute};
1515
use clone::Clone;
16-
use cmp::{Eq, Ordering, TotalEq, TotalOrd};
16+
use cmp::{Ord, Eq, Ordering, TotalEq, TotalOrd};
1717
use container::Container;
1818
use default::Default;
1919
use fmt;
@@ -136,21 +136,28 @@ impl<T> Extendable<T> for Vec<T> {
136136
}
137137
}
138138

139-
impl<T:Eq> Eq for Vec<T> {
139+
impl<T: Eq> Eq for Vec<T> {
140140
#[inline]
141141
fn eq(&self, other: &Vec<T>) -> bool {
142142
self.as_slice() == other.as_slice()
143143
}
144144
}
145145

146-
impl<T:TotalEq> TotalEq for Vec<T> {
146+
impl<T: Ord> Ord for Vec<T> {
147+
#[inline]
148+
fn lt(&self, other: &Vec<T>) -> bool {
149+
self.as_slice() < other.as_slice()
150+
}
151+
}
152+
153+
impl<T: TotalEq> TotalEq for Vec<T> {
147154
#[inline]
148155
fn equals(&self, other: &Vec<T>) -> bool {
149156
self.as_slice().equals(&other.as_slice())
150157
}
151158
}
152159

153-
impl<T:TotalOrd> TotalOrd for Vec<T> {
160+
impl<T: TotalOrd> TotalOrd for Vec<T> {
154161
#[inline]
155162
fn cmp(&self, other: &Vec<T>) -> Ordering {
156163
self.as_slice().cmp(&other.as_slice())

0 commit comments

Comments
 (0)