From 673420713e5190369f62ead10152cb7a8f1c12a7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 20 Feb 2014 19:29:21 -0500 Subject: [PATCH] require a total ordering for `Eq` and `Ord` A total ordering is assumed and required for most generic functions making use of these traits. The `cmp` method also provides a boost in efficiency for sorting sequence types or storing them in a tree set/map since otherwise two passes would often be required. The standard hardware comparison operators for floats do not implement a total order. However, IEEE754 does define an alternate total ordering. Fixing this is now issue #12434 and doesn't need to stand in the way of a sane comparison module. Traits like `PartialEq` and `PartialOrd` could exist, but will never permit a sane implementation. A type implementing `Eq` would be expected to automatically implement `PartialEq` but floating point types have *two* comparison definitions available. I don't think these would see much usage anyway, because there are even alternate definitions of functions as simple as `min`, `max` and `clamp` for floats. Closes #5283 Closes #8071 Closes #10320 --- src/doc/rust.md | 2 +- src/doc/tutorial.md | 3 +- src/etc/generate-deriving-span-tests.py | 1 - src/etc/vim/syntax/rust.vim | 4 +- src/libcollections/btree.rs | 126 ++++++++++------- src/libcollections/treemap.rs | 86 ++++++------ src/libextra/workcache.rs | 2 +- src/libglob/lib.rs | 8 +- src/libnum/bigint.rs | 26 +--- src/libnum/rational.rs | 4 +- src/librustc/back/link.rs | 2 +- src/librustc/driver/session.rs | 2 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/middle/lint.rs | 6 +- src/librustc/middle/ty.rs | 4 +- src/libstd/ascii.rs | 2 +- src/libstd/bool.rs | 11 +- src/libstd/cmp.rs | 130 +++++------------- src/libstd/io/net/ip.rs | 4 +- src/libstd/iter.rs | 29 ++-- src/libstd/managed.rs | 10 -- src/libstd/option.rs | 4 +- src/libstd/owned.rs | 10 -- src/libstd/prelude.rs | 6 +- src/libstd/reference.rs | 20 ++- src/libstd/result.rs | 2 +- src/libstd/rt/crate_map.rs | 2 +- src/libstd/rt/logging.rs | 2 +- src/libstd/str.rs | 71 +++------- src/libstd/tuple.rs | 18 --- src/libstd/unit.rs | 14 +- src/libstd/vec.rs | 50 +++---- src/libstd/vec_ng.rs | 10 +- src/libsyntax/ast.rs | 4 +- src/libsyntax/ext/deriving/cmp/ord.rs | 83 ++++++++++- src/libsyntax/ext/deriving/cmp/totaleq.rs | 47 ------- src/libsyntax/ext/deriving/cmp/totalord.rs | 118 ---------------- src/libsyntax/ext/deriving/generic.rs | 2 +- src/libsyntax/ext/deriving/mod.rs | 6 - src/libsyntax/parse/token.rs | 2 +- src/libsyntax/util/interner.rs | 12 -- src/libuuid/lib.rs | 9 -- ...riving-span-TotalEq-enum-struct-variant.rs | 26 ---- .../deriving-span-TotalEq-enum.rs | 26 ---- .../deriving-span-TotalEq-struct.rs | 24 ---- .../deriving-span-TotalEq-tuple-struct.rs | 24 ---- ...iving-span-TotalOrd-enum-struct-variant.rs | 26 ---- .../deriving-span-TotalOrd-enum.rs | 26 ---- .../deriving-span-TotalOrd-struct.rs | 24 ---- .../deriving-span-TotalOrd-tuple-struct.rs | 24 ---- .../run-pass/deriving-cmp-generic-enum.rs | 7 +- .../deriving-cmp-generic-struct-enum.rs | 7 +- .../run-pass/deriving-cmp-generic-struct.rs | 7 +- .../deriving-cmp-generic-tuple-struct.rs | 8 +- .../run-pass/deriving-cmp-shortcircuit.rs | 11 +- src/test/run-pass/deriving-global.rs | 6 +- ...deriving-self-lifetime-totalord-totaleq.rs | 31 ----- src/test/run-pass/send_str_hashmap.rs | 2 +- src/test/run-pass/send_str_treemap.rs | 2 +- src/test/run-pass/vector-sort-failure-safe.rs | 2 +- 60 files changed, 348 insertions(+), 891 deletions(-) delete mode 100644 src/libsyntax/ext/deriving/cmp/totaleq.rs delete mode 100644 src/libsyntax/ext/deriving/cmp/totalord.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalEq-enum.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalEq-struct.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalOrd-enum.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalOrd-struct.rs delete mode 100644 src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs delete mode 100644 src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs diff --git a/src/doc/rust.md b/src/doc/rust.md index 6d9cb8b5d7b72..435ba0c1638b3 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -2032,7 +2032,7 @@ impl Eq for Foo { Supported traits for `deriving` are: -* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`. +* Comparison traits: `Eq`, `Ord` * Serialization: `Encodable`, `Decodable`. These require `serialize`. * `Clone` and `DeepClone`, to perform (deep) copies. * `IterBytes`, to iterate over the bytes in a data type. diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 304dc1fb5af43..dd30a2f48862a 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -2523,8 +2523,7 @@ struct Circle { radius: f64 } enum ABC { A, B, C } ~~~ -The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, -`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`, +The full list of derivable traits is `Eq`, `Ord`, `Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Default`, `Zero`, `FromPrimitive` and `Show`. # Crates and the module system diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index cf895d2b6dee5..8b8ca2cbc1aa0 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -118,7 +118,6 @@ def write_file(name, string): for (trait, supers, errs) in [('Rand', [], 1), ('Clone', [], 1), ('DeepClone', ['Clone'], 1), ('Eq', [], 2), ('Ord', [], 8), - ('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1), ('Show', [], 1), ('Hash', [], 1)]: traits[trait] = (ALL, supers, errs) diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index d17f8fc2d877e..a18a0606b7e99 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -74,7 +74,7 @@ syn keyword rustTrait Bool syn keyword rustTrait ToCStr syn keyword rustTrait Char syn keyword rustTrait Clone DeepClone -syn keyword rustTrait Eq Ord TotalEq TotalOrd Ordering Equiv +syn keyword rustTrait Eq Ord Ordering Equiv syn keyword rustEnumVariant Less Equal Greater syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet syn keyword rustTrait Default @@ -98,7 +98,7 @@ syn keyword rustTrait ToStr IntoStr syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12 -syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCloneableVector +syn keyword rustTrait ImmutableEqVector ImmutableOrdVector ImmutableCloneableVector syn keyword rustTrait OwnedVector OwnedCloneableVector OwnedEqVector MutableVector syn keyword rustTrait Vector VectorVector CloneableVector ImmutableVector diff --git a/src/libcollections/btree.rs b/src/libcollections/btree.rs index 13b39da0756e0..85f744a2708a6 100644 --- a/src/libcollections/btree.rs +++ b/src/libcollections/btree.rs @@ -28,7 +28,7 @@ pub struct BTree { priv upper_bound: uint } -impl BTree { +impl BTree { ///Returns new BTree with root node (leaf) and user-supplied lower bound ///The lower bound applies to every node except the root node. @@ -58,7 +58,7 @@ impl BTree { //We would probably want to remove the dependence on the Clone trait in the future. //It is here as a crutch to ensure values can be passed around through the tree's nodes //especially during insertions and deletions. -impl BTree { +impl BTree { ///Returns the value of a given key, which may not exist in the tree. ///Calls the root node's get method. pub fn get(self, k: K) -> Option { @@ -83,7 +83,7 @@ impl BTree { } } -impl Clone for BTree { +impl Clone for BTree { ///Implements the Clone trait for the BTree. ///Uses a helper function/constructor to produce a new BTree. fn clone(&self) -> BTree { @@ -92,21 +92,25 @@ impl Clone for BTree { } -impl TotalEq for BTree { +impl Eq for BTree { ///Testing equality on BTrees by comparing the root. - fn equals(&self, other: &BTree) -> bool { + fn eq(&self, other: &BTree) -> bool { self.root.cmp(&other.root) == Equal } } -impl TotalOrd for BTree { +impl Ord for BTree { + fn lt(&self, other: &BTree) -> bool { + self.cmp(other) == Less + } + ///Returns an ordering based on the root nodes of each BTree. fn cmp(&self, other: &BTree) -> Ordering { self.root.cmp(&other.root) } } -impl ToStr for BTree { +impl ToStr for BTree { ///Returns a string representation of the BTree fn to_str(&self) -> ~str { let ret = self.root.to_str(); @@ -127,7 +131,7 @@ enum Node { //Node functions/methods -impl Node { +impl Node { ///Creates a new leaf node given a vector of elements. fn new_leaf(vec: ~[LeafElt]) -> Node { LeafNode(Leaf::new(vec)) @@ -157,7 +161,7 @@ impl Node { } } -impl Node { +impl Node { ///Returns the corresponding value to the provided key. ///get() is called in different ways on a branch or a leaf. fn get(&self, k: K) -> Option { @@ -176,7 +180,7 @@ impl Node { } } -impl Clone for Node { +impl Clone for Node { ///Returns a new node based on whether or not it is a branch or a leaf. fn clone(&self) -> Node { match *self { @@ -191,10 +195,10 @@ impl Clone for Node { } } -impl TotalEq for Node { +impl Eq for Node { ///Returns whether two nodes are equal based on the keys of each element. ///Two nodes are equal if all of their keys are the same. - fn equals(&self, other: &Node) -> bool{ + fn eq(&self, other: &Node) -> bool{ match *self{ BranchNode(ref branch) => { if other.is_leaf() { @@ -215,8 +219,12 @@ impl TotalEq for Node { } } -impl TotalOrd for Node { - ///Implementation of TotalOrd for Nodes. +impl Ord for Node { + fn lt(&self, other: &Node) -> bool { + self.cmp(other) == Less + } + + ///Implementation of Ord for Nodes. fn cmp(&self, other: &Node) -> Ordering { match *self { LeafNode(ref leaf) => { @@ -235,7 +243,7 @@ impl TotalOrd for Node { } } -impl ToStr for Node { +impl ToStr for Node { ///Returns a string representation of a Node. ///Will iterate over the Node and show "Key: x, value: y, child: () // " ///for all elements in the Node. "Child" only exists if the Node contains @@ -262,7 +270,7 @@ struct Branch { } -impl Leaf { +impl Leaf { ///Creates a new Leaf from a vector of LeafElts. fn new(vec: ~[LeafElt]) -> Leaf { Leaf { @@ -322,7 +330,7 @@ impl Leaf { } -impl Leaf { +impl Leaf { ///Returns the corresponding value to the supplied key. fn get(&self, k: K) -> Option { for s in self.elts.iter() { @@ -373,21 +381,25 @@ impl Leaf { } } -impl Clone for Leaf { +impl Clone for Leaf { ///Returns a new Leaf with the same elts. fn clone(&self) -> Leaf { Leaf::new(self.elts.clone()) } } -impl TotalEq for Leaf { - ///Implementation of equals function for leaves that compares LeafElts. - fn equals(&self, other: &Leaf) -> bool { - self.elts.equals(&other.elts) +impl Eq for Leaf { + ///Implementation of eq function for leaves that compares LeafElts. + fn eq(&self, other: &Leaf) -> bool { + self.elts.eq(&other.elts) } } -impl TotalOrd for Leaf { +impl Ord for Leaf { + fn lt(&self, other: &Leaf) -> bool { + self.cmp(other) == Less + } + ///Returns an ordering based on the first element of each Leaf. fn cmp(&self, other: &Leaf) -> Ordering { if self.elts.len() > other.elts.len() { @@ -401,7 +413,7 @@ impl TotalOrd for Leaf { } -impl ToStr for Leaf { +impl ToStr for Leaf { ///Returns a string representation of a Leaf. fn to_str(&self) -> ~str { self.elts.iter().map(|s| s.to_str()).to_owned_vec().connect(" // ") @@ -409,7 +421,7 @@ impl ToStr for Leaf { } -impl Branch { +impl Branch { ///Creates a new Branch from a vector of BranchElts and a rightmost child (a node). fn new(vec: ~[BranchElt], right: ~Node) -> Branch { Branch { @@ -467,7 +479,7 @@ impl Branch { } } -impl Branch { +impl Branch { ///Returns the corresponding value to the supplied key. ///If the key is not there, find the child that might hold it. fn get(&self, k: K) -> Option { @@ -591,21 +603,25 @@ impl Branch { } } -impl Clone for Branch { +impl Clone for Branch { ///Returns a new branch using the clone methods of the Branch's internal variables. fn clone(&self) -> Branch { Branch::new(self.elts.clone(), self.rightmost_child.clone()) } } -impl TotalEq for Branch { - ///Equals function for Branches--compares all the elements in each branch - fn equals(&self, other: &Branch) -> bool { - self.elts.equals(&other.elts) +impl Eq for Branch { + ///eq function for Branches--compares all the elements in each branch + fn eq(&self, other: &Branch) -> bool { + self.elts.eq(&other.elts) } } -impl TotalOrd for Branch { +impl Ord for Branch { + fn lt(&self, other: &Branch) -> bool { + self.cmp(other) == Less + } + ///Compares the first elements of two branches to determine an ordering fn cmp(&self, other: &Branch) -> Ordering { if self.elts.len() > other.elts.len() { @@ -618,7 +634,7 @@ impl TotalOrd for Branch { } } -impl ToStr for Branch { +impl ToStr for Branch { ///Returns a string representation of a Branch. fn to_str(&self) -> ~str { let mut ret = self.elts.iter().map(|s| s.to_str()).to_owned_vec().connect(" // "); @@ -641,7 +657,7 @@ struct BranchElt { value: V } -impl LeafElt { +impl LeafElt { ///Creates a new LeafElt from a supplied key-value pair. fn new(k: K, v: V) -> LeafElt { LeafElt { @@ -651,28 +667,32 @@ impl LeafElt { } } -impl Clone for LeafElt { +impl Clone for LeafElt { ///Returns a new LeafElt by cloning the key and value. fn clone(&self) -> LeafElt { LeafElt::new(self.key.clone(), self.value.clone()) } } -impl TotalEq for LeafElt { - ///TotalEq for LeafElts - fn equals(&self, other: &LeafElt) -> bool { - self.key.equals(&other.key) && self.value.equals(&other.value) +impl Eq for LeafElt { + ///Eq for LeafElts + fn eq(&self, other: &LeafElt) -> bool { + self.key.eq(&other.key) && self.value.eq(&other.value) } } -impl TotalOrd for LeafElt { +impl Ord for LeafElt { + fn lt(&self, other: &LeafElt) -> bool { + self.cmp(other) == Less + } + ///Returns an ordering based on the keys of the LeafElts. fn cmp(&self, other: &LeafElt) -> Ordering { self.key.cmp(&other.key) } } -impl ToStr for LeafElt { +impl ToStr for LeafElt { ///Returns a string representation of a LeafElt. fn to_str(&self) -> ~str { format!("Key: {}, value: {};", @@ -680,7 +700,7 @@ impl ToStr for LeafElt { } } -impl BranchElt { +impl BranchElt { ///Creates a new BranchElt from a supplied key, value, and left child. fn new(k: K, v: V, n: ~Node) -> BranchElt { BranchElt { @@ -692,7 +712,7 @@ impl BranchElt { } -impl Clone for BranchElt { +impl Clone for BranchElt { ///Returns a new BranchElt by cloning the key, value, and left child. fn clone(&self) -> BranchElt { BranchElt::new(self.key.clone(), @@ -701,21 +721,25 @@ impl Clone for BranchElt { } } -impl TotalEq for BranchElt{ - ///TotalEq for BranchElts - fn equals(&self, other: &BranchElt) -> bool { - self.key.equals(&other.key)&&self.value.equals(&other.value) +impl Eq for BranchElt{ + ///Eq for BranchElts + fn eq(&self, other: &BranchElt) -> bool { + self.key.eq(&other.key)&&self.value.eq(&other.value) } } -impl TotalOrd for BranchElt { - ///Fulfills TotalOrd for BranchElts +impl Ord for BranchElt { + fn lt(&self, other: &BranchElt) -> bool { + self.cmp(other) == Less + } + + ///Fulfills Ord for BranchElts fn cmp(&self, other: &BranchElt) -> Ordering { self.key.cmp(&other.key) } } -impl ToStr for BranchElt { +impl ToStr for BranchElt { ///Returns string containing key, value, and child (which should recur to a leaf) ///Consider changing in future to be more readable. fn to_str(&self) -> ~str { @@ -825,7 +849,7 @@ mod test_btree { fn btree_clone_test() { let b = BTree::new(1, ~"abc", 2); let b2 = b.clone(); - assert!(b.root.equals(&b2.root)) + assert!(b.root.eq(&b2.root)) } //Tests the BTree's cmp() method when one node is "less than" another. diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index a4b2357960656..c56cc18be8d45 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -10,7 +10,7 @@ //! An ordered map and set implemented as self-balancing binary search //! trees. The only requirement for the types is that the key implements -//! `TotalOrd`. +//! `Ord`. use std::iter::{Peekable}; use std::cmp::Ordering; @@ -42,7 +42,7 @@ pub struct TreeMap { priv length: uint } -impl Eq for TreeMap { +impl Eq for TreeMap { fn eq(&self, other: &TreeMap) -> bool { self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b) @@ -50,8 +50,8 @@ impl Eq for TreeMap { } // Lexicographical comparison -fn lt(a: &TreeMap, - b: &TreeMap) -> bool { +fn lt(a: &TreeMap, + b: &TreeMap) -> bool { // the Zip iterator is as long as the shortest of a and b. for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) { if *key_a < *key_b { return true; } @@ -63,7 +63,7 @@ fn lt(a: &TreeMap, a.len() < b.len() } -impl Ord for TreeMap { +impl Ord for TreeMap { #[inline] fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } #[inline] @@ -74,7 +74,7 @@ impl Ord for TreeMap { fn gt(&self, other: &TreeMap) -> bool { lt(other, self) } } -impl Container for TreeMap { +impl Container for TreeMap { /// Return the number of elements in the map fn len(&self) -> uint { self.length } @@ -82,7 +82,7 @@ impl Container for TreeMap { fn is_empty(&self) -> bool { self.root.is_none() } } -impl Mutable for TreeMap { +impl Mutable for TreeMap { /// Clear the map, removing all key-value pairs. fn clear(&mut self) { self.root = None; @@ -90,7 +90,7 @@ impl Mutable for TreeMap { } } -impl Map for TreeMap { +impl Map for TreeMap { /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V> { let mut current: &'a Option<~TreeNode> = &self.root; @@ -109,7 +109,7 @@ impl Map for TreeMap { } } -impl MutableMap for TreeMap { +impl MutableMap for TreeMap { /// Return a mutable reference to the value corresponding to the key #[inline] fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { @@ -133,7 +133,7 @@ impl MutableMap for TreeMap { } } -impl TreeMap { +impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } @@ -219,7 +219,7 @@ macro_rules! bound_setup { } -impl TreeMap { +impl TreeMap { /// Get a lazy iterator that should be initialized using /// `traverse_left`/`traverse_right`/`traverse_complete`. fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> { @@ -550,20 +550,20 @@ impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { /// A implementation of the `Set` trait on top of the `TreeMap` container. The /// only requirement is that the type of the elements contained ascribes to the -/// `TotalOrd` trait. +/// `Ord` trait. #[deriving(Clone)] pub struct TreeSet { priv map: TreeMap } -impl Eq for TreeSet { +impl Eq for TreeSet { #[inline] fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } #[inline] fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } -impl Ord for TreeSet { +impl Ord for TreeSet { #[inline] fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } #[inline] @@ -574,7 +574,7 @@ impl Ord for TreeSet { fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } } -impl Container for TreeSet { +impl Container for TreeSet { /// Return the number of elements in the set #[inline] fn len(&self) -> uint { self.map.len() } @@ -584,13 +584,13 @@ impl Container for TreeSet { fn is_empty(&self) -> bool { self.map.is_empty() } } -impl Mutable for TreeSet { +impl Mutable for TreeSet { /// Clear the set, removing all values. #[inline] fn clear(&mut self) { self.map.clear() } } -impl Set for TreeSet { +impl Set for TreeSet { /// Return true if the set contains a value #[inline] fn contains(&self, value: &T) -> bool { @@ -635,7 +635,7 @@ impl Set for TreeSet { } } -impl MutableSet for TreeSet { +impl MutableSet for TreeSet { /// Add a value to the set. Return true if the value was not already /// present in the set. #[inline] @@ -647,7 +647,7 @@ impl MutableSet for TreeSet { fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } } -impl TreeSet { +impl TreeSet { /// Create an empty TreeSet #[inline] pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } @@ -738,7 +738,7 @@ pub struct UnionItems<'a, T> { } /// Compare `x` and `y`, but return `short` if x is None and `long` if y is None -fn cmp_opt(x: Option<&T>, y: Option<&T>, +fn cmp_opt(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering { match (x, y) { (None , _ ) => short, @@ -747,7 +747,7 @@ fn cmp_opt(x: Option<&T>, y: Option<&T>, } } -impl<'a, T: TotalOrd> Iterator<&'a T> for DifferenceItems<'a, T> { +impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { @@ -759,7 +759,7 @@ impl<'a, T: TotalOrd> Iterator<&'a T> for DifferenceItems<'a, T> { } } -impl<'a, T: TotalOrd> Iterator<&'a T> for SymDifferenceItems<'a, T> { +impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { @@ -771,7 +771,7 @@ impl<'a, T: TotalOrd> Iterator<&'a T> for SymDifferenceItems<'a, T> { } } -impl<'a, T: TotalOrd> Iterator<&'a T> for IntersectionItems<'a, T> { +impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> { fn next(&mut self) -> Option<&'a T> { loop { let o_cmp = match (self.a.peek(), self.b.peek()) { @@ -789,7 +789,7 @@ impl<'a, T: TotalOrd> Iterator<&'a T> for IntersectionItems<'a, T> { } } -impl<'a, T: TotalOrd> Iterator<&'a T> for UnionItems<'a, T> { +impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { @@ -813,7 +813,7 @@ struct TreeNode { level: uint } -impl TreeNode { +impl TreeNode { /// Creates a new tree node. #[inline] pub fn new(key: K, value: V) -> TreeNode { @@ -822,7 +822,7 @@ impl TreeNode { } // Remove left horizontal link by rotating right -fn skew(node: &mut ~TreeNode) { +fn skew(node: &mut ~TreeNode) { if node.left.as_ref().map_or(false, |x| x.level == node.level) { let mut save = node.left.take_unwrap(); swap(&mut node.left, &mut save.right); // save.right now None @@ -833,7 +833,7 @@ fn skew(node: &mut ~TreeNode) { // Remove dual horizontal link by rotating left and increasing level of // the parent -fn split(node: &mut ~TreeNode) { +fn split(node: &mut ~TreeNode) { if node.right.as_ref().map_or(false, |x| x.right.as_ref().map_or(false, |y| y.level == node.level)) { let mut save = node.right.take_unwrap(); @@ -844,7 +844,7 @@ fn split(node: &mut ~TreeNode) { } } -fn find_mut<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, +fn find_mut<'r, K: Ord, V>(node: &'r mut Option<~TreeNode>, key: &K) -> Option<&'r mut V> { match *node { @@ -859,7 +859,7 @@ fn find_mut<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, } } -fn insert(node: &mut Option<~TreeNode>, +fn insert(node: &mut Option<~TreeNode>, key: K, value: V) -> Option { match *node { Some(ref mut save) => { @@ -889,9 +889,9 @@ fn insert(node: &mut Option<~TreeNode>, } } -fn remove(node: &mut Option<~TreeNode>, +fn remove(node: &mut Option<~TreeNode>, key: &K) -> Option { - fn heir_swap(node: &mut ~TreeNode, + fn heir_swap(node: &mut ~TreeNode, child: &mut Option<~TreeNode>) { // *could* be done without recursion, but it won't borrow check for x in child.mut_iter() { @@ -972,7 +972,7 @@ fn remove(node: &mut Option<~TreeNode>, }; } -impl FromIterator<(K, V)> for TreeMap { +impl FromIterator<(K, V)> for TreeMap { fn from_iterator>(iter: &mut T) -> TreeMap { let mut map = TreeMap::new(); map.extend(iter); @@ -980,7 +980,7 @@ impl FromIterator<(K, V)> for TreeMap { } } -impl Extendable<(K, V)> for TreeMap { +impl Extendable<(K, V)> for TreeMap { #[inline] fn extend>(&mut self, iter: &mut T) { for (k, v) in *iter { @@ -989,7 +989,7 @@ impl Extendable<(K, V)> for TreeMap { } } -impl FromIterator for TreeSet { +impl FromIterator for TreeSet { fn from_iterator>(iter: &mut Iter) -> TreeSet { let mut set = TreeSet::new(); set.extend(iter); @@ -997,7 +997,7 @@ impl FromIterator for TreeSet { } } -impl Extendable for TreeSet { +impl Extendable for TreeSet { #[inline] fn extend>(&mut self, iter: &mut Iter) { for elem in *iter { @@ -1008,7 +1008,7 @@ impl Extendable for TreeSet { impl< E: Encoder, - K: Encodable + Eq + TotalOrd, + K: Encodable + Eq + Ord, V: Encodable + Eq > Encodable for TreeMap { fn encode(&self, e: &mut E) { @@ -1025,7 +1025,7 @@ impl< impl< D: Decoder, - K: Decodable + Eq + TotalOrd, + K: Decodable + Eq + Ord, V: Decodable + Eq > Decodable for TreeMap { fn decode(d: &mut D) -> TreeMap { @@ -1043,7 +1043,7 @@ impl< impl< S: Encoder, - T: Encodable + Eq + TotalOrd + T: Encodable + Eq + Ord > Encodable for TreeSet { fn encode(&self, s: &mut S) { s.emit_seq(self.len(), |s| { @@ -1058,7 +1058,7 @@ impl< impl< D: Decoder, - T: Decodable + Eq + TotalOrd + T: Decodable + Eq + Ord > Decodable for TreeSet { fn decode(d: &mut D) -> TreeSet { d.read_seq(|d, len| { @@ -1146,7 +1146,7 @@ mod test_treemap { assert_eq!(m.find(&k1), Some(&v1)); } - fn check_equal(ctrl: &[(K, V)], + fn check_equal(ctrl: &[(K, V)], map: &TreeMap) { assert_eq!(ctrl.is_empty(), map.is_empty()); for x in ctrl.iter() { @@ -1167,7 +1167,7 @@ mod test_treemap { } } - fn check_left(node: &Option<~TreeNode>, + fn check_left(node: &Option<~TreeNode>, parent: &~TreeNode) { match *node { Some(ref r) => { @@ -1180,7 +1180,7 @@ mod test_treemap { } } - fn check_right(node: &Option<~TreeNode>, + fn check_right(node: &Option<~TreeNode>, parent: &~TreeNode, parent_red: bool) { match *node { @@ -1197,7 +1197,7 @@ mod test_treemap { } } - fn check_structure(map: &TreeMap) { + fn check_structure(map: &TreeMap) { match map.root { Some(ref r) => { check_left(&r.left, r); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 007b54adbe51a..3423bd31d4e40 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -87,7 +87,7 @@ use std::io::{File, MemWriter}; * */ -#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)] +#[deriving(Clone, Eq, Ord, Encodable, Decodable)] struct WorkKey { kind: ~str, name: ~str diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs index 3a93b10ad29c8..247ed79194351 100644 --- a/src/libglob/lib.rs +++ b/src/libglob/lib.rs @@ -165,12 +165,12 @@ fn list_dir_sorted(path: &Path) -> ~[Path] { /** * A compiled Unix shell style pattern. */ -#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)] +#[deriving(Clone, Eq, Ord, IterBytes, Default)] pub struct Pattern { priv tokens: ~[PatternToken] } -#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)] +#[deriving(Clone, Eq, Ord, IterBytes)] enum PatternToken { Char(char), AnyChar, @@ -179,7 +179,7 @@ enum PatternToken { AnyExcept(~[CharSpecifier]) } -#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)] +#[deriving(Clone, Eq, Ord, IterBytes)] enum CharSpecifier { SingleChar(char), CharRange(char, char) @@ -490,7 +490,7 @@ fn chars_eq(a: char, b: char, case_sensitive: bool) -> bool { /** * Configuration options to modify the behaviour of `Pattern::matches_with(..)` */ -#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)] +#[deriving(Clone, Eq, Ord, IterBytes, Default)] pub struct MatchOptions { /** diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index 0418c61d361b4..31a0fb8cd6b19 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -19,7 +19,7 @@ A `BigInt` is a combination of `BigUint` and `Sign`. use Integer; use std::cmp; -use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; +use std::cmp::{Eq, Ord, Ordering, Less, Equal, Greater}; use std::num::{Zero, One, ToStrRadix, FromStrRadix}; use std::num::{Bitwise, ToPrimitive, FromPrimitive}; use std::rand::Rng; @@ -89,12 +89,7 @@ pub struct BigUint { impl Eq for BigUint { #[inline] - fn eq(&self, other: &BigUint) -> bool { self.equals(other) } -} - -impl TotalEq for BigUint { - #[inline] - fn equals(&self, other: &BigUint) -> bool { + fn eq(&self, other: &BigUint) -> bool { match self.cmp(other) { Equal => true, _ => false } } } @@ -104,9 +99,7 @@ impl Ord for BigUint { fn lt(&self, other: &BigUint) -> bool { match self.cmp(other) { Less => true, _ => false} } -} -impl TotalOrd for BigUint { #[inline] fn cmp(&self, other: &BigUint) -> Ordering { let (s_len, o_len) = (self.data.len(), other.data.len()); @@ -835,13 +828,7 @@ impl Ord for Sign { fn lt(&self, other: &Sign) -> bool { match self.cmp(other) { Less => true, _ => false} } -} -impl TotalEq for Sign { - #[inline] - fn equals(&self, other: &Sign) -> bool { *self == *other } -} -impl TotalOrd for Sign { #[inline] fn cmp(&self, other: &Sign) -> Ordering { match (*self, *other) { @@ -873,12 +860,7 @@ pub struct BigInt { impl Eq for BigInt { #[inline] - fn eq(&self, other: &BigInt) -> bool { self.equals(other) } -} - -impl TotalEq for BigInt { - #[inline] - fn equals(&self, other: &BigInt) -> bool { + fn eq(&self, other: &BigInt) -> bool { match self.cmp(other) { Equal => true, _ => false } } } @@ -888,9 +870,7 @@ impl Ord for BigInt { fn lt(&self, other: &BigInt) -> bool { match self.cmp(other) { Less => true, _ => false} } -} -impl TotalOrd for BigInt { #[inline] fn cmp(&self, other: &BigInt) -> Ordering { let scmp = self.sign.cmp(&other.sign); diff --git a/src/libnum/rational.rs b/src/libnum/rational.rs index 5f1868b48c519..3aa9d07c11711 100644 --- a/src/libnum/rational.rs +++ b/src/libnum/rational.rs @@ -158,9 +158,7 @@ macro_rules! cmp_impl { }; } cmp_impl!(impl Eq, eq, ne) -cmp_impl!(impl TotalEq, equals) -cmp_impl!(impl Ord, lt, gt, le, ge) -cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering) +cmp_impl!(impl Ord, lt -> bool, gt -> bool, le -> bool, ge -> bool, cmp -> cmp::Ordering) /* Arithmetic */ // a/b * c/d = (a*c)/(b*d) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index bd0748761ee7a..e71312878b332 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -46,7 +46,7 @@ use syntax::attr::AttrMetaMethods; use syntax::crateid::CrateId; use syntax::parse::token; -#[deriving(Clone, Eq, TotalOrd, TotalEq)] +#[deriving(Clone, Eq, Ord)] pub enum OutputType { OutputTypeBitcode, OutputTypeAssembly, diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e023190e5f4e7..2f9d128776c88 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -157,7 +157,7 @@ pub enum EntryFnType { EntryNone, } -#[deriving(Eq, Clone, TotalOrd, TotalEq)] +#[deriving(Eq, Ord, Clone)] pub enum CrateType { CrateTypeExecutable, CrateTypeDylib, diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 1a8b86b351061..8cc2447fa8153 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -220,7 +220,7 @@ impl CStore { } } -#[deriving(Clone, TotalEq, TotalOrd)] +#[deriving(Clone, Eq, Ord)] struct crate_hash { name: ~str, vers: ~str, diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 36ed4913cdb0c..a5c3fa31d9ce6 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -69,7 +69,7 @@ use syntax::parse::token; use syntax::visit::Visitor; use syntax::{ast, ast_util, visit}; -#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] +#[deriving(Clone, Eq, Ord)] pub enum Lint { CTypes, UnusedImports, @@ -123,12 +123,12 @@ pub fn level_to_str(lv: level) -> &'static str { } } -#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] +#[deriving(Clone, Eq, Ord)] pub enum level { allow, warn, deny, forbid } -#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] +#[deriving(Clone, Eq, Ord)] pub struct LintSpec { default: level, lint: Lint, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c7aedec4b4834..7f251e73b717f 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -620,13 +620,13 @@ impl Region { } } -#[deriving(Clone, Eq, TotalOrd, TotalEq, IterBytes, Encodable, Decodable, ToStr, Show)] +#[deriving(Clone, Eq, Ord, IterBytes, Encodable, Decodable, ToStr)] pub struct FreeRegion { scope_id: NodeId, bound_region: BoundRegion } -#[deriving(Clone, Eq, TotalEq, TotalOrd, IterBytes, Encodable, Decodable, ToStr, Show)] +#[deriving(Clone, Eq, Ord, IterBytes, Encodable, Decodable, ToStr, Show)] pub enum BoundRegion { /// An anonymous region parameter for a given fn (&T) BrAnon(uint), diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 651d364dd1b97..933f207e1733d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -24,7 +24,7 @@ use to_bytes::IterBytes; use option::{Option, Some, None}; /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero. -#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)] +#[deriving(Clone, Eq, Ord)] pub struct Ascii { priv chr: u8 } impl Ascii { diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs index af745f94fb519..5ee0d1607eb48 100644 --- a/src/libstd/bool.rs +++ b/src/libstd/bool.rs @@ -20,7 +20,6 @@ //! * `ToStr` //! * `Not` //! * `Ord` -//! * `TotalOrd` //! * `Eq` //! * `Default` //! * `Zero` @@ -37,7 +36,7 @@ use from_str::FromStr; use to_str::ToStr; use num::FromPrimitive; -#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering}; +#[cfg(not(test))] use cmp::{Eq, Ord}; #[cfg(not(test))] use ops::{Not, BitAnd, BitOr, BitXor}; #[cfg(not(test))] use default::Default; @@ -279,12 +278,6 @@ impl Ord for bool { fn lt(&self, other: &bool) -> bool { self.to_bit::() < other.to_bit() } } -#[cfg(not(test))] -impl TotalOrd for bool { - #[inline] - fn cmp(&self, other: &bool) -> Ordering { self.to_bit::().cmp(&other.to_bit()) } -} - /// Equality between two boolean values. /// /// Two booleans are equal if they have the same value. @@ -426,7 +419,7 @@ mod tests { } #[test] - fn test_bool_totalord() { + fn test_bool_cmp() { assert_eq!(true.cmp(&true), Equal); assert_eq!(false.cmp(&false), Equal); assert_eq!(true.cmp(&false), Greater); diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index de9f836ca5eb6..a609e2b5a1c6d 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -22,16 +22,18 @@ and `Eq` to overload the `==` and `!=` operators. #[allow(missing_doc)]; -/** -* Trait for values that can be compared for equality and inequality. +/** Equality relation * -* This trait allows partial equality, where types can be unordered instead of strictly equal or -* unequal. For example, with the built-in floating-point types `a == b` and `a != b` will both -* evaluate to false if either `a` or `b` is NaN (cf. IEEE 754-2008 section 5.11). +* This trait provides comparisons for equality and inquality. * -* Eq only requires the `eq` method to be implemented; `ne` is its negation by default. +* Requirements: +* +* `a != b` returns the same value as `!(a == b)` +* `a == a` is true +* `a == b` implies `b == a` +* `a == b && b == c` implies `a == c` * -* Eventually, this will be implemented by default for types that implement `TotalEq`. +* Eq only requires the `eq` method to be implemented; `ne` is its negation by default. */ #[lang="eq"] pub trait Eq { @@ -41,93 +43,16 @@ pub trait Eq { fn ne(&self, other: &Self) -> bool { !self.eq(other) } } -/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses. -pub trait TotalEq { - fn equals(&self, other: &Self) -> bool; -} - -macro_rules! totaleq_impl( - ($t:ty) => { - impl TotalEq for $t { - #[inline] - fn equals(&self, other: &$t) -> bool { *self == *other } - } - } -) - -totaleq_impl!(bool) - -totaleq_impl!(u8) -totaleq_impl!(u16) -totaleq_impl!(u32) -totaleq_impl!(u64) - -totaleq_impl!(i8) -totaleq_impl!(i16) -totaleq_impl!(i32) -totaleq_impl!(i64) - -totaleq_impl!(int) -totaleq_impl!(uint) - -totaleq_impl!(char) - #[deriving(Clone, Eq)] pub enum Ordering { Less = -1, Equal = 0, Greater = 1 } -/// Trait for types that form a total order -pub trait TotalOrd: TotalEq { - fn cmp(&self, other: &Self) -> Ordering; -} - -impl TotalEq for Ordering { - #[inline] - fn equals(&self, other: &Ordering) -> bool { - *self == *other - } -} -impl TotalOrd for Ordering { - #[inline] - fn cmp(&self, other: &Ordering) -> Ordering { - (*self as int).cmp(&(*other as int)) - } -} - impl Ord for Ordering { #[inline] fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) } } -macro_rules! totalord_impl( - ($t:ty) => { - impl TotalOrd for $t { - #[inline] - fn cmp(&self, other: &$t) -> Ordering { - if *self < *other { Less } - else if *self > *other { Greater } - else { Equal } - } - } - } -) - -totalord_impl!(u8) -totalord_impl!(u16) -totalord_impl!(u32) -totalord_impl!(u64) - -totalord_impl!(i8) -totalord_impl!(i16) -totalord_impl!(i32) -totalord_impl!(i64) - -totalord_impl!(int) -totalord_impl!(uint) - -totalord_impl!(char) - /// Compares (a1, b1) against (a2, b2), where the a values are more significant. -pub fn cmp2( +pub fn cmp2( a1: &A, b1: &B, a2: &A, b2: &B) -> Ordering { @@ -150,26 +75,43 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering { } } -/** -* Trait for values that can be compared for a sort-order. +/** Strict total ordering +* +* This trait provides sort order comparisons. +* +* Ord only requires implementation of the `lt` method, with the others +* generated from default implementations. * -* Ord only requires implementation of the `lt` method, -* with the others generated from default implementations. +* The `cmp` method allows for an efficient three-way comparison implementation. * -* However it remains possible to implement the others separately, -* for compatibility with floating-point NaN semantics -* (cf. IEEE 754-2008 section 5.11). +* The default implementation of `cmp` should be overridden with a single-pass +* implementation for ordered container types (vectors, strings, tree-based +* maps/sets). +* +* Generic wrapper types (like smart pointers) should override `cmp` and call +* the underlying `cmp` method for efficiency. A derived implementation will do +* this automatically. */ #[lang="ord"] -pub trait Ord { +pub trait Ord: Eq { fn lt(&self, other: &Self) -> bool; + #[inline] fn le(&self, other: &Self) -> bool { !other.lt(self) } + #[inline] fn gt(&self, other: &Self) -> bool { other.lt(self) } + #[inline] fn ge(&self, other: &Self) -> bool { !self.lt(other) } + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + if *self < *other { Less } + else if *self > *other { Greater } + else { Equal } + } + // FIXME (#12068): Add min/max/clamp default methods } @@ -196,7 +138,7 @@ mod test { use super::lexical_ordering; #[test] - fn test_int_totalord() { + fn test_int_cmp() { assert_eq!(5.cmp(&10), Less); assert_eq!(10.cmp(&5), Greater); assert_eq!(5.cmp(&5), Equal); diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index f042661117ea3..c4729ae05ccfb 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -19,7 +19,7 @@ use vec::{MutableCloneableVector, ImmutableVector, MutableVector}; pub type Port = u16; -#[deriving(Eq, TotalEq, Clone, IterBytes)] +#[deriving(Eq, Clone, IterBytes)] pub enum IpAddr { Ipv4Addr(u8, u8, u8, u8), Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16) @@ -49,7 +49,7 @@ impl ToStr for IpAddr { } } -#[deriving(Eq, TotalEq, Clone, IterBytes)] +#[deriving(Eq, Clone, IterBytes)] pub struct SocketAddr { ip: IpAddr, port: Port, diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 5e919e4ac0a4d..bb7749e76a748 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -2191,23 +2191,12 @@ impl RandomAccessIterator for Repeat { /// the shorter sequence compares less. pub mod order { use cmp; - use cmp::{TotalEq, TotalOrd, Ord, Eq}; + use cmp::{Ord, Eq}; use option::{Some, None}; use super::Iterator; - /// Compare `a` and `b` for equality using `TotalOrd` - pub fn equals>(mut a: T, mut b: T) -> bool { - loop { - match (a.next(), b.next()) { - (None, None) => return true, - (None, _) | (_, None) => return false, - (Some(x), Some(y)) => if !x.equals(&y) { return false }, - } - } - } - - /// Order `a` and `b` lexicographically using `TotalOrd` - pub fn cmp>(mut a: T, mut b: T) -> cmp::Ordering { + /// Order `a` and `b` lexicographically + pub fn cmp>(mut a: T, mut b: T) -> cmp::Ordering { loop { match (a.next(), b.next()) { (None, None) => return cmp::Equal, @@ -2221,7 +2210,7 @@ pub mod order { } } - /// Compare `a` and `b` for equality (Using partial equality, `Eq`) + /// Compare `a` and `b` for equality pub fn eq>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { @@ -2232,7 +2221,7 @@ pub mod order { } } - /// Compare `a` and `b` for nonequality (Using partial equality, `Eq`) + /// Compare `a` and `b` for nonequality pub fn ne>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { @@ -2243,7 +2232,7 @@ pub mod order { } } - /// Return `a` < `b` lexicographically (Using partial order, `Ord`) + /// Return `a` < `b` lexicographically pub fn lt>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { @@ -2255,7 +2244,7 @@ pub mod order { } } - /// Return `a` <= `b` lexicographically (Using partial order, `Ord`) + /// Return `a` <= `b` lexicographically pub fn le>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { @@ -2267,7 +2256,7 @@ pub mod order { } } - /// Return `a` > `b` lexicographically (Using partial order, `Ord`) + /// Return `a` > `b` lexicographically pub fn gt>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { @@ -2279,7 +2268,7 @@ pub mod order { } } - /// Return `a` >= `b` lexicographically (Using partial order, `Ord`) + /// Return `a` >= `b` lexicographically pub fn ge>(mut a: T, mut b: T) -> bool { loop { match (a.next(), b.next()) { diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index 4cd99492ee458..d589111485f54 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -43,20 +43,10 @@ impl Ord for @T { fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) } #[inline] fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) } -} - -#[cfg(not(test))] -impl TotalOrd for @T { #[inline] fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) } } -#[cfg(not(test))] -impl TotalEq for @T { - #[inline] - fn equals(&self, other: &@T) -> bool { (**self).equals(*other) } -} - #[test] fn test() { let x = @3; diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 44d78be93d624..4562075d0bdb3 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -40,7 +40,7 @@ use any::Any; use clone::Clone; use clone::DeepClone; -use cmp::{Eq, TotalEq, TotalOrd}; +use cmp::Eq; use default::Default; use fmt; use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize}; @@ -51,7 +51,7 @@ use to_str::ToStr; use vec; /// The option type -#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)] +#[deriving(Clone, DeepClone, Eq, Ord, ToStr)] pub enum Option { /// No value None, diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs index dc8ea34c84bd3..ee48373caec5b 100644 --- a/src/libstd/owned.rs +++ b/src/libstd/owned.rs @@ -44,16 +44,6 @@ impl Ord for ~T { fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) } #[inline] fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) } -} - -#[cfg(not(test))] -impl TotalOrd for ~T { #[inline] fn cmp(&self, other: &~T) -> Ordering { (**self).cmp(*other) } } - -#[cfg(not(test))] -impl TotalEq for ~T { - #[inline] - fn equals(&self, other: &~T) -> bool { (**self).equals(*other) } -} diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 83ef85fc35b4a..da615e450e520 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -41,7 +41,7 @@ pub use bool::Bool; pub use c_str::ToCStr; pub use char::Char; pub use clone::{Clone, DeepClone}; -pub use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv}; +pub use cmp::{Eq, Ord, Ordering, Less, Equal, Greater, Equiv}; pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; pub use default::Default; pub use from_str::FromStr; @@ -60,9 +60,9 @@ pub use to_str::{ToStr, IntoStr}; pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; -pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCloneableVector}; +pub use vec::{ImmutableEqVector, ImmutableOrdVector, ImmutableCloneableVector}; pub use vec::{OwnedVector, OwnedCloneableVector, OwnedEqVector}; -pub use vec::{MutableVector, MutableTotalOrdVector}; +pub use vec::{MutableVector, MutableOrdVector}; pub use vec::{Vector, VectorVector, CloneableVector, ImmutableVector}; // Reexported runtime types diff --git a/src/libstd/reference.rs b/src/libstd/reference.rs index fdbca2b9f3322..752fc0774b892 100644 --- a/src/libstd/reference.rs +++ b/src/libstd/reference.rs @@ -11,7 +11,7 @@ //! Utilities for references #[cfg(not(test))] -use cmp::{Eq, Ord, Ordering, TotalEq, TotalOrd}; +use cmp::{Eq, Ord, Ordering}; // Equality for region pointers #[cfg(not(test))] @@ -20,6 +20,7 @@ impl<'a, T: Eq> Eq for &'a T { fn eq(&self, other: & &'a T) -> bool { *(*self) == *(*other) } + #[inline] fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) @@ -33,29 +34,24 @@ impl<'a, T: Ord> Ord for &'a T { fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) } + #[inline] fn le(&self, other: & &'a T) -> bool { *(*self) <= *(*other) } + #[inline] fn ge(&self, other: & &'a T) -> bool { *(*self) >= *(*other) } + #[inline] fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) } -} - -#[cfg(not(test))] -impl<'a, T: TotalOrd> TotalOrd for &'a T { - #[inline] - fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) } -} -#[cfg(not(test))] -impl<'a, T: TotalEq> TotalEq for &'a T { #[inline] - fn equals(&self, other: & &'a T) -> bool { (**self).equals(*other) } + fn cmp(&self, other: & &'a T) -> Ordering { + (**self).cmp(*other) + } } - diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 39e8b6ad6c1d2..1fd8f5ece4d5b 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -19,7 +19,7 @@ use str::OwnedStr; use to_str::ToStr; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). -#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)] +#[deriving(Clone, DeepClone, Eq, Ord, ToStr)] #[must_use] pub enum Result { /// Contains the success value diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs index 847375121c89d..7b571269f7028 100644 --- a/src/libstd/rt/crate_map.rs +++ b/src/libstd/rt/crate_map.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use cmp::TotalOrd; +use cmp::Ord; use container::MutableSet; use iter::Iterator; use option::{Some, None, Option}; diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index b86a9612d7061..8da16c339c56b 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -15,7 +15,7 @@ use libc::exit; use option::{Some, None, Option}; use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map}; use str::StrSlice; -use vec::{ImmutableVector, MutableTotalOrdVector, OwnedVector}; +use vec::{ImmutableVector, MutableOrdVector, OwnedVector}; #[cfg(test)] use cast::transmute; struct LogDirective { diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 4d5eabbed104e..c24b85588ff74 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -86,7 +86,7 @@ use cast::transmute; use char; use char::Char; use clone::{Clone, DeepClone}; -use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv, Ordering}; +use cmp::{Eq, Ord, Equiv, Ordering}; use container::{Container, Mutable}; use fmt; use iter::{Iterator, FromIterator, Extendable, range}; @@ -869,7 +869,7 @@ pub struct UTF16Items<'a> { priv iter: vec::Items<'a, u16> } /// The possibilities for values decoded from a `u16` stream. -#[deriving(Eq, TotalEq, Clone)] +#[deriving(Eq, Clone)] pub enum UTF16Item { /// A valid codepoint. ScalarValue(char), @@ -1276,14 +1276,7 @@ impl<'a> ToStr for MaybeOwned<'a> { impl<'a> Eq for MaybeOwned<'a> { #[inline] fn eq(&self, other: &MaybeOwned) -> bool { - self.as_slice().equals(&other.as_slice()) - } -} - -impl<'a> TotalEq for MaybeOwned<'a> { - #[inline] - fn equals(&self, other: &MaybeOwned) -> bool { - self.as_slice().equals(&other.as_slice()) + self.as_slice().eq(&other.as_slice()) } } @@ -1292,9 +1285,7 @@ impl<'a> Ord for MaybeOwned<'a> { fn lt(&self, other: &MaybeOwned) -> bool { self.as_slice().lt(&other.as_slice()) } -} -impl<'a> TotalOrd for MaybeOwned<'a> { #[inline] fn cmp(&self, other: &MaybeOwned) -> Ordering { self.as_slice().cmp(&other.as_slice()) @@ -1304,7 +1295,7 @@ impl<'a> TotalOrd for MaybeOwned<'a> { impl<'a, S: Str> Equiv for MaybeOwned<'a> { #[inline] fn equiv(&self, other: &S) -> bool { - self.as_slice().equals(&other.as_slice()) + self.as_slice().eq(&other.as_slice()) } } @@ -1542,7 +1533,7 @@ Section: Trait implementations #[allow(missing_doc)] pub mod traits { use container::Container; - use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq}; + use cmp::{Ordering, Less, Equal, Greater, Eq, Ord, Equiv}; use iter::Iterator; use ops::Add; use option::{Some, None}; @@ -1557,26 +1548,6 @@ pub mod traits { } } - impl<'a> TotalOrd for &'a str { - #[inline] - fn cmp(&self, other: & &'a 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()) - } - } - - impl TotalOrd for ~str { - #[inline] - fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } - } - impl<'a> Eq for &'a str { #[inline] fn eq(&self, other: & &'a str) -> bool { @@ -1593,28 +1564,30 @@ pub mod traits { } } - impl<'a> TotalEq for &'a str { + impl<'a> Ord for &'a str { #[inline] - fn equals(&self, other: & &'a str) -> bool { - eq_slice((*self), (*other)) - } - } + fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less } - impl TotalEq for ~str { #[inline] - fn equals(&self, other: &~str) -> bool { - eq_slice((*self), (*other)) - } - } + fn cmp(&self, other: & &'a 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 => () + } + } - impl<'a> Ord for &'a str { - #[inline] - fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less } + self.len().cmp(&other.len()) + } } impl Ord for ~str { #[inline] fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less } + + #[inline] + fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) } } impl<'a, S: Str> Equiv for &'a str { @@ -4460,11 +4433,11 @@ mod tests { assert_eq!(Owned(~""), Default::default()); assert_eq!(s.cmp(&o), Equal); - assert!(s.equals(&o)); + assert!(s.eq(&o)); assert!(s.equiv(&o)); assert_eq!(o.cmp(&s), Equal); - assert!(o.equals(&s)); + assert!(o.eq(&s)); assert!(o.equiv(&s)); } diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index b0d51cba103d4..640737ceb1340 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -75,14 +75,6 @@ macro_rules! tuple_impls { } } - #[cfg(not(test))] - impl<$($T:TotalEq),+> TotalEq for ($($T,)+) { - #[inline] - fn equals(&self, other: &($($T,)+)) -> bool { - $(self.$refN().equals(other.$refN()))&&+ - } - } - #[cfg(not(test))] impl<$($T:Ord + Eq),+> Ord for ($($T,)+) { #[inline] @@ -101,10 +93,7 @@ macro_rules! tuple_impls { fn gt(&self, other: &($($T,)+)) -> bool { lexical_ord!(gt, $(self.$refN(), other.$refN()),+) } - } - #[cfg(not(test))] - impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { lexical_cmp!($(self.$refN(), other.$refN()),+) @@ -345,13 +334,6 @@ mod tests { assert!(((1.0, 2.0) < (2.0, nan))); assert!(!((2.0, 2.0) < (2.0, nan))); - // TotalEq - assert!(small.equals(&small)); - assert!(big.equals(&big)); - assert!(!small.equals(&big)); - assert!(!big.equals(&small)); - - // TotalOrd assert_eq!(small.cmp(&small), Equal); assert_eq!(big.cmp(&big), Equal); assert_eq!(small.cmp(&big), Less); diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs index b23dafbca6970..0c6ee9474b642 100644 --- a/src/libstd/unit.rs +++ b/src/libstd/unit.rs @@ -13,7 +13,7 @@ #[cfg(not(test))] use default::Default; #[cfg(not(test))] -use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd}; +use cmp::{Eq, Ord}; use fmt; #[cfg(not(test))] @@ -30,18 +30,6 @@ impl Ord for () { fn lt(&self, _other: &()) -> bool { false } } -#[cfg(not(test))] -impl TotalOrd for () { - #[inline] - fn cmp(&self, _other: &()) -> Ordering { Equal } -} - -#[cfg(not(test))] -impl TotalEq for () { - #[inline] - fn equals(&self, _other: &()) -> bool { true } -} - #[cfg(not(test))] impl Default for () { #[inline] diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index d8cb8bf3ed19f..fd6ab0eb593fc 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -65,7 +65,7 @@ Vectors are a very useful type, and so there's several implementations of traits from other modules. Some notable examples: * `Clone` -* `Eq`, `Ord`, `TotalEq`, `TotalOrd` -- vectors can be compared, +* `Eq`, `Ord` -- vectors can be compared, if the element type defines the corresponding trait. ## Iteration @@ -106,7 +106,7 @@ use cast::transmute; use ops::Drop; use clone::{Clone, DeepClone}; use container::{Container, Mutable}; -use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater}; +use cmp::{Eq, Ord, Ordering, Less, Equal, Greater}; use cmp; use default::Default; use fmt; @@ -627,7 +627,7 @@ pub mod traits { use container::Container; use clone::Clone; - use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv}; + use cmp::{Eq, Ord, Ordering, Equiv}; use iter::order; use ops::Add; @@ -649,18 +649,6 @@ pub mod traits { fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } - impl<'a,T:TotalEq> TotalEq for &'a [T] { - fn equals(&self, other: & &'a [T]) -> bool { - self.len() == other.len() && - order::equals(self.iter(), other.iter()) - } - } - - impl TotalEq for ~[T] { - #[inline] - fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) } - } - impl<'a,T:Eq, V: Vector> Equiv for &'a [T] { #[inline] fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } @@ -671,17 +659,6 @@ pub mod traits { fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } - impl<'a,T:TotalOrd> TotalOrd for &'a [T] { - fn cmp(&self, other: & &'a [T]) -> Ordering { - order::cmp(self.iter(), other.iter()) - } - } - - impl TotalOrd for ~[T] { - #[inline] - fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } - } - impl<'a, T: Eq + Ord> Ord for &'a [T] { fn lt(&self, other: & &'a [T]) -> bool { order::lt(self.iter(), other.iter()) @@ -698,17 +675,28 @@ pub mod traits { fn gt(&self, other: & &'a [T]) -> bool { order::gt(self.iter(), other.iter()) } + + #[inline] + fn cmp(&self, other: & &'a [T]) -> Ordering { + order::cmp(self.iter(), other.iter()) + } } impl Ord for ~[T] { #[inline] fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() } + + #[inline] + fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } } impl<'a,T:Clone, V: Vector> Add for &'a [T] { @@ -1205,8 +1193,8 @@ impl<'a,T:Eq> ImmutableEqVector for &'a [T] { } } -/// Extension methods for vectors containing `TotalOrd` elements. -pub trait ImmutableTotalOrdVector { +/// Extension methods for vectors containing `Ord` elements. +pub trait ImmutableOrdVector { /** * Binary search a sorted vector for a given element. * @@ -1215,7 +1203,7 @@ pub trait ImmutableTotalOrdVector { fn bsearch_elem(&self, x: &T) -> Option; } -impl<'a, T: TotalOrd> ImmutableTotalOrdVector for &'a [T] { +impl<'a, T: Ord> ImmutableOrdVector for &'a [T] { fn bsearch_elem(&self, x: &T) -> Option { self.bsearch(|p| p.cmp(x)) } @@ -2447,7 +2435,7 @@ impl<'a, T:Clone> MutableCloneableVector for &'a mut [T] { /// Methods for mutable vectors with orderable elements, such as /// in-place sorting. -pub trait MutableTotalOrdVector { +pub trait MutableOrdVector { /// Sort the vector, in place. /// /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. @@ -2462,7 +2450,7 @@ pub trait MutableTotalOrdVector { /// ``` fn sort(self); } -impl<'a, T: TotalOrd> MutableTotalOrdVector for &'a mut [T] { +impl<'a, T: Ord> MutableOrdVector for &'a mut [T] { #[inline] fn sort(self) { self.sort_by(|a,b| a.cmp(b)) diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs index 3532e7b26a405..7b6a8c8ed5774 100644 --- a/src/libstd/vec_ng.rs +++ b/src/libstd/vec_ng.rs @@ -13,7 +13,7 @@ use cast::{forget, transmute}; use clone::Clone; -use cmp::{Eq, Ordering, TotalEq, TotalOrd}; +use cmp::{Eq, Ordering, Less, Ord}; use container::Container; use iter::{DoubleEndedIterator, FromIterator, Iterator}; use libc::{free, c_void}; @@ -109,14 +109,12 @@ impl Eq for Vec { } } -impl TotalEq for Vec { +impl Ord for Vec { #[inline] - fn equals(&self, other: &Vec) -> bool { - self.as_slice().equals(&other.as_slice()) + fn lt(&self, other: &Vec) -> bool { + self.cmp(other) == Less } -} -impl TotalOrd for Vec { #[inline] fn cmp(&self, other: &Vec) -> Ordering { self.as_slice().cmp(&other.as_slice()) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index db1243b18bc2d..55332d57915dd 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -39,7 +39,7 @@ pub fn P(value: T) -> P { // table) and a SyntaxContext to track renaming and // macro expansion per Flatt et al., "Macros // That Work Together" -#[deriving(Clone, IterBytes, ToStr, TotalEq, TotalOrd, Show)] +#[deriving(Clone, IterBytes, ToStr, Ord, Show)] pub struct Ident { name: Name, ctxt: SyntaxContext } impl Ident { @@ -177,7 +177,7 @@ pub type CrateNum = u32; pub type NodeId = u32; -#[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, IterBytes, ToStr, Show)] +#[deriving(Clone, Ord, Eq, Encodable, Decodable, IterBytes, ToStr, Show)] pub struct DefId { krate: CrateNum, node: NodeId, diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 10a416045cbda..601497d334474 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -45,7 +45,17 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt, md!("lt", true, false), md!("le", true, true), md!("gt", false, false), - md!("ge", false, true) + md!("ge", false, true), + MethodDef { + name: "cmp", + generics: LifetimeBounds::empty(), + explicit_self: borrowed_explicit_self(), + args: ~[borrowed_self()], + ret_ty: Literal(Path::new(~["std", "cmp", "Ordering"])), + inline: true, + const_nonmatching: false, + combine_substructure: cs_cmp + } ] }; trait_def.expand(cx, mitem, item, push) @@ -105,3 +115,74 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substru }, cx, span, substr) } + +fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path { + let cnst = match cnst { + Less => "Less", + Equal => "Equal", + Greater => "Greater" + }; + cx.path_global(span, + ~[cx.ident_of("std"), + cx.ident_of("cmp"), + cx.ident_of(cnst)]) +} + +fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { + let test_id = cx.ident_of("__test"); + let equals_path = ordering_const(cx, span, Equal); + + /* + Builds: + + let __test = self_field1.cmp(&other_field2); + if other == ::std::cmp::Equal { + let __test = self_field2.cmp(&other_field2); + if __test == ::std::cmp::Equal { + ... + } else { + __test + } + } else { + __test + } + + FIXME #6449: These `if`s could/should be `match`es. + */ + cs_same_method_fold( + // foldr nests the if-elses correctly, leaving the first field + // as the outermost one, and the last as the innermost. + false, + |cx, span, old, new| { + // let __test = new; + // if __test == ::std::cmp::Equal { + // old + // } else { + // __test + // } + + let assign = cx.stmt_let(span, false, test_id, new); + + let cond = cx.expr_binary(span, ast::BiEq, + cx.expr_ident(span, test_id), + cx.expr_path(equals_path.clone())); + let if_ = cx.expr_if(span, + cond, + old, Some(cx.expr_ident(span, test_id))); + cx.expr_block(cx.block(span, ~[assign], Some(if_))) + }, + cx.expr_path(equals_path.clone()), + |cx, span, list, _| { + match list { + // an earlier nonmatching variant is Less than a + // later one. + [(self_var, _, _), + (other_var, _, _)] => { + let order = ordering_const(cx, span, self_var.cmp(&other_var)); + cx.expr_path(order) + } + _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(TotalOrd)`") + } + }, + cx, span, substr) +} diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs deleted file mode 100644 index 2bfab8646a6aa..0000000000000 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast::{MetaItem, Item, Expr}; -use codemap::Span; -use ext::base::ExtCtxt; -use ext::build::AstBuilder; -use ext::deriving::generic::*; - -pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, - span: Span, - mitem: @MetaItem, - item: @Item, - push: |@Item|) { - fn cs_equals(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { - cs_and(|cx, span, _, _| cx.expr_bool(span, false), - cx, span, substr) - } - - let trait_def = TraitDef { - span: span, - attributes: ~[], - path: Path::new(~["std", "cmp", "TotalEq"]), - additional_bounds: ~[], - generics: LifetimeBounds::empty(), - methods: ~[ - MethodDef { - name: "equals", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: ~[borrowed_self()], - ret_ty: Literal(Path::new(~["bool"])), - inline: true, - const_nonmatching: true, - combine_substructure: cs_equals - } - ] - }; - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs deleted file mode 100644 index 2e6c4a5422892..0000000000000 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast; -use ast::{MetaItem, Item, Expr}; -use codemap::Span; -use ext::base::ExtCtxt; -use ext::build::AstBuilder; -use ext::deriving::generic::*; -use std::cmp::{Ordering, Equal, Less, Greater}; - -pub fn expand_deriving_totalord(cx: &mut ExtCtxt, - span: Span, - mitem: @MetaItem, - item: @Item, - push: |@Item|) { - let trait_def = TraitDef { - span: span, - attributes: ~[], - path: Path::new(~["std", "cmp", "TotalOrd"]), - additional_bounds: ~[], - generics: LifetimeBounds::empty(), - methods: ~[ - MethodDef { - name: "cmp", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: ~[borrowed_self()], - ret_ty: Literal(Path::new(~["std", "cmp", "Ordering"])), - inline: true, - const_nonmatching: false, - combine_substructure: cs_cmp - } - ] - }; - - trait_def.expand(cx, mitem, item, push) -} - - -pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path { - let cnst = match cnst { - Less => "Less", - Equal => "Equal", - Greater => "Greater" - }; - cx.path_global(span, - ~[cx.ident_of("std"), - cx.ident_of("cmp"), - cx.ident_of(cnst)]) -} - -pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, - substr: &Substructure) -> @Expr { - let test_id = cx.ident_of("__test"); - let equals_path = ordering_const(cx, span, Equal); - - /* - Builds: - - let __test = self_field1.cmp(&other_field2); - if other == ::std::cmp::Equal { - let __test = self_field2.cmp(&other_field2); - if __test == ::std::cmp::Equal { - ... - } else { - __test - } - } else { - __test - } - - FIXME #6449: These `if`s could/should be `match`es. - */ - cs_same_method_fold( - // foldr nests the if-elses correctly, leaving the first field - // as the outermost one, and the last as the innermost. - false, - |cx, span, old, new| { - // let __test = new; - // if __test == ::std::cmp::Equal { - // old - // } else { - // __test - // } - - let assign = cx.stmt_let(span, false, test_id, new); - - let cond = cx.expr_binary(span, ast::BiEq, - cx.expr_ident(span, test_id), - cx.expr_path(equals_path.clone())); - let if_ = cx.expr_if(span, - cond, - old, Some(cx.expr_ident(span, test_id))); - cx.expr_block(cx.block(span, ~[assign], Some(if_))) - }, - cx.expr_path(equals_path.clone()), - |cx, span, list, _| { - match list { - // an earlier nonmatching variant is Less than a - // later one. - [(self_var, _, _), - (other_var, _, _)] => { - let order = ordering_const(cx, span, self_var.cmp(&other_var)); - cx.expr_path(order) - } - _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(TotalOrd)`") - } - }, - cx, span, substr) -} diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 99ac07ba4d7b0..47679746667a1 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -27,7 +27,7 @@ Supported features (fairly exhaustive): moment. (`TraitDef.additional_bounds`) Unsupported: FIXME #6257: calling methods on reference fields, -e.g. deriving TotalEq/TotalOrd/Clone don't work on `struct A(&int)`, +e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`, because of how the auto-dereferencing happens. The most important thing for implementers is the `Substructure` and diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 31ee99fbd260e..da2e6e225e34b 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -36,12 +36,8 @@ pub mod primitive; #[path="cmp/eq.rs"] pub mod eq; -#[path="cmp/totaleq.rs"] -pub mod totaleq; #[path="cmp/ord.rs"] pub mod ord; -#[path="cmp/totalord.rs"] -pub mod totalord; pub mod generic; @@ -81,9 +77,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt, "Decodable" => expand!(decodable::expand_deriving_decodable), "Eq" => expand!(eq::expand_deriving_eq), - "TotalEq" => expand!(totaleq::expand_deriving_totaleq), "Ord" => expand!(ord::expand_deriving_ord), - "TotalOrd" => expand!(totalord::expand_deriving_totalord), "Rand" => expand!(rand::expand_deriving_rand), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index b264e8d7467ba..de7ef9e0dca9e 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -536,7 +536,7 @@ pub fn get_ident_interner() -> @IdentInterner { /// destroyed. In particular, they must not access string contents. This can /// be fixed in the future by just leaking all strings until task death /// somehow. -#[deriving(Clone, Eq, IterBytes, Ord, TotalEq, TotalOrd)] +#[deriving(Clone, Eq, IterBytes, Ord)] pub struct InternedString { priv string: RcStr, } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 44b366c989076..cd2a5a0df0a6a 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -90,18 +90,6 @@ pub struct RcStr { priv string: Rc<~str>, } -impl TotalEq for RcStr { - fn equals(&self, other: &RcStr) -> bool { - self.as_slice().equals(&other.as_slice()) - } -} - -impl TotalOrd for RcStr { - fn cmp(&self, other: &RcStr) -> Ordering { - self.as_slice().cmp(&other.as_slice()) - } -} - impl Str for RcStr { #[inline] fn as_slice<'a>(&'a self) -> &'a str { diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index e4053e3bc3879..b8adcef6127ea 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -480,15 +480,6 @@ impl Eq for Uuid { } } -/// Test two UUIDs for equality -/// -/// UUIDs are equal only when they are byte-for-byte identical -impl TotalEq for Uuid { - fn equals(&self, other: &Uuid) -> bool { - self.bytes == other.bytes - } -} - // FIXME #9845: Test these more thoroughly impl Encodable for Uuid { /// Encode a UUID as a hypenated string diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs deleted file mode 100644 index f054e9e7e77f6..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - - -struct Error; - -#[deriving(TotalEq)] -enum Enum { - A { - x: Error //~ ERROR - } -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum.rs b/src/test/compile-fail/deriving-span-TotalEq-enum.rs deleted file mode 100644 index 38b8d55bcd83a..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalEq-enum.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - - -struct Error; - -#[deriving(TotalEq)] -enum Enum { - A( - Error //~ ERROR - ) -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalEq-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-struct.rs deleted file mode 100644 index 66e5ef57a00b5..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalEq-struct.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - - -struct Error; - -#[deriving(TotalEq)] -struct Struct { - x: Error //~ ERROR -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs deleted file mode 100644 index dd0be2dc04a65..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - - -struct Error; - -#[deriving(TotalEq)] -struct Struct( - Error //~ ERROR -); - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs deleted file mode 100644 index 76bcd33256240..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - -#[deriving(TotalEq)] -struct Error; - -#[deriving(TotalOrd,TotalEq)] -enum Enum { - A { - x: Error //~ ERROR - } -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum.rs deleted file mode 100644 index 303e35108feea..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalOrd-enum.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - -#[deriving(TotalEq)] -struct Error; - -#[deriving(TotalOrd,TotalEq)] -enum Enum { - A( - Error //~ ERROR - ) -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalOrd-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-struct.rs deleted file mode 100644 index bbcc3ae7e047a..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalOrd-struct.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - -#[deriving(TotalEq)] -struct Error; - -#[deriving(TotalOrd,TotalEq)] -struct Struct { - x: Error //~ ERROR -} - -fn main() {} diff --git a/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs deleted file mode 100644 index 4e8697749e76e..0000000000000 --- a/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' - -#[feature(struct_variant)]; -extern crate extra; - -#[deriving(TotalEq)] -struct Error; - -#[deriving(TotalOrd,TotalEq)] -struct Struct( - Error //~ ERROR -); - -fn main() {} diff --git a/src/test/run-pass/deriving-cmp-generic-enum.rs b/src/test/run-pass/deriving-cmp-generic-enum.rs index 094d17c100ebd..1072e0746e5bb 100644 --- a/src/test/run-pass/deriving-cmp-generic-enum.rs +++ b/src/test/run-pass/deriving-cmp-generic-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving(Eq, TotalEq, Ord, TotalOrd)] +#[deriving(Eq, Ord)] enum E { E0, E1(T), @@ -22,7 +22,6 @@ pub fn main() { let e21 = E2(1, 1); let e22 = E2(1, 2); - // in order for both Ord and TotalOrd let es = [e0, e11, e12, e21, e22]; for (i, e1) in es.iter().enumerate() { @@ -39,9 +38,6 @@ pub fn main() { assert_eq!(*e1 == *e2, eq); assert_eq!(*e1 != *e2, !eq); - // TotalEq - assert_eq!(e1.equals(e2), eq); - // Ord assert_eq!(*e1 < *e2, lt); assert_eq!(*e1 > *e2, gt); @@ -49,7 +45,6 @@ pub fn main() { assert_eq!(*e1 <= *e2, le); assert_eq!(*e1 >= *e2, ge); - // TotalOrd assert_eq!(e1.cmp(e2), ord); } } diff --git a/src/test/run-pass/deriving-cmp-generic-struct-enum.rs b/src/test/run-pass/deriving-cmp-generic-struct-enum.rs index aedf4732afdbb..1f8089fbbd491 100644 --- a/src/test/run-pass/deriving-cmp-generic-struct-enum.rs +++ b/src/test/run-pass/deriving-cmp-generic-struct-enum.rs @@ -10,7 +10,7 @@ #[feature(struct_variant)]; -#[deriving(Eq, TotalEq, Ord, TotalOrd)] +#[deriving(Eq, Ord)] enum ES { ES1 { x: T }, ES2 { x: T, y: T } @@ -20,7 +20,6 @@ enum ES { pub fn main() { let (es11, es12, es21, es22) = (ES1 {x: 1}, ES1 {x: 2}, ES2 {x: 1, y: 1}, ES2 {x: 1, y: 2}); - // in order for both Ord and TotalOrd let ess = [es11, es12, es21, es22]; for (i, es1) in ess.iter().enumerate() { @@ -35,9 +34,6 @@ pub fn main() { assert_eq!(*es1 == *es2, eq); assert_eq!(*es1 != *es2, !eq); - // TotalEq - assert_eq!(es1.equals(es2), eq); - // Ord assert_eq!(*es1 < *es2, lt); assert_eq!(*es1 > *es2, gt); @@ -45,7 +41,6 @@ pub fn main() { assert_eq!(*es1 <= *es2, le); assert_eq!(*es1 >= *es2, ge); - // TotalOrd assert_eq!(es1.cmp(es2), ord); } } diff --git a/src/test/run-pass/deriving-cmp-generic-struct.rs b/src/test/run-pass/deriving-cmp-generic-struct.rs index d04bdee34e611..656e2f5dd98ae 100644 --- a/src/test/run-pass/deriving-cmp-generic-struct.rs +++ b/src/test/run-pass/deriving-cmp-generic-struct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving(Eq, TotalEq, Ord, TotalOrd)] +#[deriving(Eq, Ord)] struct S { x: T, y: T @@ -18,7 +18,6 @@ pub fn main() { let s1 = S {x: 1, y: 1}; let s2 = S {x: 1, y: 2}; - // in order for both Ord and TotalOrd let ss = [s1, s2]; for (i, s1) in ss.iter().enumerate() { @@ -35,9 +34,6 @@ pub fn main() { assert_eq!(*s1 == *s2, eq); assert_eq!(*s1 != *s2, !eq); - // TotalEq - assert_eq!(s1.equals(s2), eq); - // Ord assert_eq!(*s1 < *s2, lt); assert_eq!(*s1 > *s2, gt); @@ -45,7 +41,6 @@ pub fn main() { assert_eq!(*s1 <= *s2, le); assert_eq!(*s1 >= *s2, ge); - // TotalOrd assert_eq!(s1.cmp(s2), ord); } } diff --git a/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs b/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs index 5d4cf7c745769..c7eae292b8202 100644 --- a/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs +++ b/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deriving(Eq, TotalEq, Ord, TotalOrd)] +#[deriving(Eq, Ord)] struct TS(T,T); - pub fn main() { let ts1 = TS(1, 1); let ts2 = TS(1, 2); - // in order for both Ord and TotalOrd let tss = [ts1, ts2]; for (i, ts1) in tss.iter().enumerate() { @@ -33,9 +31,6 @@ pub fn main() { assert_eq!(*ts1 == *ts2, eq); assert_eq!(*ts1 != *ts2, !eq); - // TotalEq - assert_eq!(ts1.equals(ts2), eq); - // Ord assert_eq!(*ts1 < *ts2, lt); assert_eq!(*ts1 > *ts2, gt); @@ -43,7 +38,6 @@ pub fn main() { assert_eq!(*ts1 <= *ts2, le); assert_eq!(*ts1 >= *ts2, ge); - // TotalOrd assert_eq!(ts1.cmp(ts2), ord); } } diff --git a/src/test/run-pass/deriving-cmp-shortcircuit.rs b/src/test/run-pass/deriving-cmp-shortcircuit.rs index 431c856ee88a5..945f117df0e0b 100644 --- a/src/test/run-pass/deriving-cmp-shortcircuit.rs +++ b/src/test/run-pass/deriving-cmp-shortcircuit.rs @@ -21,15 +21,7 @@ impl Ord for FailCmp { fn lt(&self, _: &FailCmp) -> bool { fail!("lt") } } -impl TotalEq for FailCmp { - fn equals(&self, _: &FailCmp) -> bool { fail!("equals") } -} - -impl TotalOrd for FailCmp { - fn cmp(&self, _: &FailCmp) -> Ordering { fail!("cmp") } -} - -#[deriving(Eq,Ord,TotalEq,TotalOrd)] +#[deriving(Eq, Ord)] struct ShortCircuit { x: int, y: FailCmp @@ -41,6 +33,5 @@ pub fn main() { assert!(a != b); assert!(a < b); - assert!(!a.equals(&b)); assert_eq!(a.cmp(&b), ::std::cmp::Less); } diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs index 544a8c2b00af8..6dcee810399e5 100644 --- a/src/test/run-pass/deriving-global.rs +++ b/src/test/run-pass/deriving-global.rs @@ -26,21 +26,21 @@ mod submod { // if any of these are implemented without global calls for any // function calls, then being in a submodule will (correctly) // cause errors about unrecognised module `std` (or `extra`) - #[deriving(Eq, Ord, TotalEq, TotalOrd, + #[deriving(Eq, Ord, IterBytes, Clone, DeepClone, ToStr, Rand, Encodable, Decodable)] enum A { A1(uint), A2(int) } - #[deriving(Eq, Ord, TotalEq, TotalOrd, + #[deriving(Eq, Ord, IterBytes, Clone, DeepClone, ToStr, Rand, Encodable, Decodable)] struct B { x: uint, y: int } - #[deriving(Eq, Ord, TotalEq, TotalOrd, + #[deriving(Eq, Ord, IterBytes, Clone, DeepClone, ToStr, Rand, diff --git a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs deleted file mode 100644 index 723738495e757..0000000000000 --- a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-test FIXME #11820: & is unreliable in deriving - -use std::cmp::{Less,Equal,Greater}; - -#[deriving(TotalEq,TotalOrd)] -struct A<'a> { - x: &'a int -} -pub fn main() { - let (a, b) = (A { x: &1 }, A { x: &2 }); - - assert!(a.equals(&a)); - assert!(b.equals(&b)); - - - assert_eq!(a.cmp(&a), Equal); - assert_eq!(b.cmp(&b), Equal); - - assert_eq!(a.cmp(&b), Less); - assert_eq!(b.cmp(&a), Greater); -} diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index 4fd7980e7955d..42f2efb0cb955 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -11,7 +11,7 @@ extern crate collections; use std::clone::{Clone, DeepClone}; -use std::cmp::{TotalEq, Ord, TotalOrd, Equiv}; +use std::cmp::{Ord, Equiv}; use std::cmp::Equal; use std::container::{Container, Map, MutableMap}; use std::default::Default; diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index 1543d34ae88b9..591f0be61a708 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -11,7 +11,7 @@ extern crate collections; use std::clone::{Clone, DeepClone}; -use std::cmp::{TotalEq, Ord, TotalOrd, Equiv}; +use std::cmp::{Ord, Equiv}; use std::cmp::Equal; use std::container::{Container, Map, MutableMap}; use std::default::Default; diff --git a/src/test/run-pass/vector-sort-failure-safe.rs b/src/test/run-pass/vector-sort-failure-safe.rs index 74f27e480909c..1ac2b85f3a876 100644 --- a/src/test/run-pass/vector-sort-failure-safe.rs +++ b/src/test/run-pass/vector-sort-failure-safe.rs @@ -15,7 +15,7 @@ static MAX_LEN: uint = 20; static mut drop_counts: [uint, .. MAX_LEN] = [0, .. MAX_LEN]; static mut clone_count: uint = 0; -#[deriving(Rand, Ord, TotalEq, TotalOrd)] +#[deriving(Rand, Ord)] struct DropCounter { x: uint, clone_num: uint } impl Clone for DropCounter {