std: remove the equals method from TotalEq.

`TotalEq` is now just an assertion about the `Eq` impl of a
type (i.e. `==` is a total equality if a type implements `TotalEq`) so
the extra method is just confusing.

Also, a new method magically appeared as a hack to allow deriving to
assert that the contents of a struct/enum are also TotalEq, because the
deriving infrastructure makes it very hard to do anything but create a
trait method. (You didn't hear about this horrible work-around from me
:(.)
This commit is contained in:
Huon Wilson 2014-03-23 22:54:42 +11:00
parent 2ddb605654
commit f6db0ef946
23 changed files with 74 additions and 208 deletions

View file

@ -337,7 +337,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
}
}
if tool_path.equals(&~"") {
if tool_path.is_empty() {
fatal(~"cannot found android cross path");
}

View file

@ -94,17 +94,12 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for BTree<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for BTree<K, V> {
fn eq(&self, other: &BTree<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
///Testing equality on BTrees by comparing the root.
fn equals(&self, other: &BTree<K, V>) -> bool {
self.root.cmp(&other.root) == Equal
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {}
impl<K: TotalOrd, V: TotalEq> Ord for BTree<K, V> {
fn lt(&self, other: &BTree<K, V>) -> bool {
self.cmp(other) == Less
@ -204,14 +199,6 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for Node<K, V> {
fn eq(&self, other: &Node<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
///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<K, V>) -> bool{
match *self{
BranchNode(ref branch) => {
if other.is_leaf() {
@ -232,6 +219,8 @@ impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {}
impl<K: TotalOrd, V: TotalEq> Ord for Node<K, V> {
fn lt(&self, other: &Node<K, V>) -> bool {
self.cmp(other) == Less
@ -405,16 +394,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Leaf<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for Leaf<K, V> {
fn eq(&self, other: &Leaf<K, V>) -> bool {
self.equals(other)
self.elts == other.elts
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Leaf<K, V> {
///Implementation of equals function for leaves that compares LeafElts.
fn equals(&self, other: &Leaf<K, V>) -> bool {
self.elts.equals(&other.elts)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Leaf<K, V> {}
impl<K: TotalOrd, V: TotalEq> Ord for Leaf<K, V> {
fn lt(&self, other: &Leaf<K, V>) -> bool {
@ -639,16 +623,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for Branch<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for Branch<K, V> {
fn eq(&self, other: &Branch<K, V>) -> bool {
self.equals(other)
self.elts == other.elts
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Branch<K, V> {
///Equals function for Branches--compares all the elements in each branch
fn equals(&self, other: &Branch<K, V>) -> bool {
self.elts.equals(&other.elts)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Branch<K, V> {}
impl<K: TotalOrd, V: TotalEq> Ord for Branch<K, V> {
fn lt(&self, other: &Branch<K, V>) -> bool {
@ -712,16 +691,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for LeafElt<K, V> {
fn eq(&self, other: &LeafElt<K, V>) -> bool {
self.equals(other)
self.key == other.key && self.value == other.value
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for LeafElt<K, V> {
///TotalEq for LeafElts
fn equals(&self, other: &LeafElt<K, V>) -> bool {
self.key.equals(&other.key) && self.value.equals(&other.value)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for LeafElt<K, V> {}
impl<K: TotalOrd, V: TotalEq> Ord for LeafElt<K, V> {
fn lt(&self, other: &LeafElt<K, V>) -> bool {
@ -766,16 +740,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V> {
impl<K: TotalOrd, V: TotalEq> Eq for BranchElt<K, V>{
fn eq(&self, other: &BranchElt<K, V>) -> bool {
self.equals(other)
self.key == other.key && self.value == other.value
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BranchElt<K, V>{
///TotalEq for BranchElts
fn equals(&self, other: &BranchElt<K, V>) -> bool {
self.key.equals(&other.key)&&self.value.equals(&other.value)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BranchElt<K, V>{}
impl<K: TotalOrd, V: TotalEq> Ord for BranchElt<K, V> {
fn lt(&self, other: &BranchElt<K, V>) -> bool {
@ -900,7 +869,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 == b2.root)
}
//Tests the BTree's cmp() method when one node is "less than" another.

View file

@ -92,15 +92,11 @@ 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 }
}
}
impl TotalEq for BigUint {}
impl Ord for BigUint {
#[inline]
@ -852,31 +848,9 @@ fn get_radix_base(radix: uint) -> (uint, uint) {
}
/// A Sign is a `BigInt`'s composing element.
#[deriving(Eq, Clone, Show)]
#[deriving(Eq, Ord, TotalEq, TotalOrd, Clone, Show)]
pub enum Sign { Minus, Zero, Plus }
impl Ord for Sign {
#[inline]
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) {
(Minus, Minus) | (Zero, Zero) | (Plus, Plus) => Equal,
(Minus, Zero) | (Minus, Plus) | (Zero, Plus) => Less,
_ => Greater
}
}
}
impl Neg<Sign> for Sign {
/// Negate Sign value.
#[inline]
@ -898,16 +872,13 @@ 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 }
}
}
impl TotalEq for BigInt {}
impl Ord for BigInt {
#[inline]
fn lt(&self, other: &BigInt) -> bool {

View file

@ -147,20 +147,20 @@ macro_rules! cmp_impl {
cmp_impl!(impl $imp, $($method -> bool),+)
};
// return something other than a Ratio<T>
(impl $imp:ident, $($method:ident -> $res:ty),+) => {
(impl $imp:ident, $($method:ident -> $res:ty),*) => {
impl<T: Mul<T,T> + $imp> $imp for Ratio<T> {
$(
#[inline]
fn $method(&self, other: &Ratio<T>) -> $res {
(self.numer * other.denom). $method (&(self.denom*other.numer))
}
)+
)*
}
};
}
cmp_impl!(impl Eq, eq, ne)
cmp_impl!(impl TotalEq, equals)
cmp_impl!(impl Ord, lt, gt, le, ge)
cmp_impl!(impl TotalEq, )
cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering)
/* Arithmetic */

View file

@ -42,6 +42,21 @@ pub trait Eq {
}
/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
#[cfg(not(stage0))]
pub trait TotalEq: Eq {
// FIXME #13101: this method is used solely by #[deriving] to
// assert that every component of a type implements #[deriving]
// itself, the current deriving infrastructure means doing this
// assertion without using a method on this trait is nearly
// impossible.
//
// This should never be implemented by hand.
#[doc(hidden)]
#[inline(always)]
fn assert_receiver_is_total_eq(&self) {}
}
#[cfg(stage0)]
pub trait TotalEq: Eq {
/// This method must return the same value as `eq`. It exists to prevent
/// deriving `TotalEq` from fields not implementing the `TotalEq` trait.
@ -52,10 +67,7 @@ pub trait TotalEq: Eq {
macro_rules! totaleq_impl(
($t:ty) => {
impl TotalEq for $t {
#[inline]
fn equals(&self, other: &$t) -> bool { *self == *other }
}
impl TotalEq for $t {}
}
)
@ -84,12 +96,7 @@ pub trait TotalOrd: TotalEq + Ord {
fn cmp(&self, other: &Self) -> Ordering;
}
impl TotalEq for Ordering {
#[inline]
fn equals(&self, other: &Ordering) -> bool {
*self == *other
}
}
impl TotalEq for Ordering {}
impl TotalOrd for Ordering {
#[inline]
fn cmp(&self, other: &Ordering) -> Ordering {
@ -194,12 +201,6 @@ mod test {
assert_eq!(12.cmp(-5), Greater);
}
#[test]
fn test_int_totaleq() {
assert!(5.equals(&5));
assert!(!2.equals(&17));
}
#[test]
fn test_ordering_order() {
assert!(Less < Equal);

View file

@ -2195,13 +2195,13 @@ pub mod order {
use option::{Some, None};
use super::Iterator;
/// Compare `a` and `b` for equality using `TotalOrd`
/// Compare `a` and `b` for equality using `TotalEq`
pub fn equals<A: TotalEq, T: Iterator<A>>(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 },
(Some(x), Some(y)) => if x != y { return false },
}
}
}

View file

@ -45,10 +45,7 @@ impl<T: TotalOrd> TotalOrd for @T {
}
#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @T {
#[inline]
fn equals(&self, other: &@T) -> bool { (**self).equals(*other) }
}
impl<T: TotalEq> TotalEq for @T {}
#[test]
fn test() {

View file

@ -53,7 +53,4 @@ impl<T: TotalOrd> TotalOrd for ~T {
}
#[cfg(not(test))]
impl<T: TotalEq> TotalEq for ~T {
#[inline]
fn equals(&self, other: &~T) -> bool { (**self).equals(*other) }
}
impl<T: TotalEq> TotalEq for ~T {}

View file

@ -54,8 +54,4 @@ impl<'a, T: TotalOrd> TotalOrd for &'a T {
}
#[cfg(not(test))]
impl<'a, T: TotalEq> TotalEq for &'a T {
#[inline]
fn equals(&self, other: & &'a T) -> bool { (**self).equals(*other) }
}
impl<'a, T: TotalEq> TotalEq for &'a T {}

View file

@ -649,17 +649,9 @@ 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<'a,T:TotalEq> TotalEq for &'a [T] {}
impl<T:TotalEq> TotalEq for ~[T] {
#[inline]
fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
}
impl<T:TotalEq> TotalEq for ~[T] {}
impl<'a,T:Eq, V: Vector<T>> Equiv<V> for &'a [T] {
#[inline]

View file

@ -1262,16 +1262,11 @@ impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
impl<'a> Eq for MaybeOwned<'a> {
#[inline]
fn eq(&self, other: &MaybeOwned) -> bool {
self.as_slice().equals(&other.as_slice())
self.as_slice() == other.as_slice()
}
}
impl<'a> TotalEq for MaybeOwned<'a> {
#[inline]
fn equals(&self, other: &MaybeOwned) -> bool {
self.as_slice().equals(&other.as_slice())
}
}
impl<'a> TotalEq for MaybeOwned<'a> {}
impl<'a> Ord for MaybeOwned<'a> {
#[inline]
@ -1290,7 +1285,7 @@ impl<'a> TotalOrd for MaybeOwned<'a> {
impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
#[inline]
fn equiv(&self, other: &S) -> bool {
self.as_slice().equals(&other.as_slice())
self.as_slice() == other.as_slice()
}
}
@ -1577,19 +1572,9 @@ pub mod traits {
}
}
impl<'a> TotalEq for &'a str {
#[inline]
fn equals(&self, other: & &'a str) -> bool {
eq_slice((*self), (*other))
}
}
impl<'a> TotalEq for &'a str {}
impl TotalEq for ~str {
#[inline]
fn equals(&self, other: &~str) -> bool {
eq_slice((*self), (*other))
}
}
impl TotalEq for ~str {}
impl<'a> Ord for &'a str {
#[inline]
@ -4450,11 +4435,9 @@ mod tests {
assert_eq!(Owned(~""), Default::default());
assert!(s.cmp(&o) == Equal);
assert!(s.equals(&o));
assert!(s.equiv(&o));
assert!(o.cmp(&s) == Equal);
assert!(o.equals(&s));
assert!(o.equiv(&s));
}

View file

@ -75,12 +75,7 @@ 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()))&&+
}
}
impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {}
#[cfg(not(test))]
impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
@ -338,12 +333,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!(small.cmp(&small) == Equal);
assert!(big.cmp(&big) == Equal);

View file

@ -37,10 +37,7 @@ impl TotalOrd for () {
}
#[cfg(not(test))]
impl TotalEq for () {
#[inline]
fn equals(&self, _other: &()) -> bool { true }
}
impl TotalEq for () {}
#[cfg(not(test))]
impl Default for () {

View file

@ -339,12 +339,7 @@ impl<T: Ord> Ord for Vec<T> {
}
}
impl<T: TotalEq> TotalEq for Vec<T> {
#[inline]
fn equals(&self, other: &Vec<T>) -> bool {
self.as_slice().equals(&other.as_slice())
}
}
impl<T: TotalEq> TotalEq for Vec<T> {}
impl<T: TotalOrd> TotalOrd for Vec<T> {
#[inline]

View file

@ -19,9 +19,18 @@ pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
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)
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
cs_same_method(|cx, span, exprs| {
// create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`)
let stmts = exprs.move_iter().map(|e| cx.stmt_expr(e)).collect();
let block = cx.block(span, stmts, None);
cx.expr_block(block)
},
|cx, sp, _, _| cx.span_bug(sp, "non matching enums in deriving(TotalEq)?"),
cx,
span,
substr)
}
let trait_def = TraitDef {
@ -32,14 +41,14 @@ pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
methods: vec!(
MethodDef {
name: "equals",
name: "assert_receiver_is_total_eq",
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
args: vec!(),
ret_ty: nil_ty(),
inline: true,
const_nonmatching: true,
combine_substructure: cs_equals
combine_substructure: cs_total_eq_assert
}
)
};

View file

@ -95,11 +95,7 @@ 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 TotalEq for RcStr {}
impl TotalOrd for RcStr {
fn cmp(&self, other: &RcStr) -> Ordering {

View file

@ -491,14 +491,7 @@ 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
}
}
impl TotalEq for Uuid {}
// FIXME #9845: Test these more thoroughly
impl<T: Encoder> Encodable<T> for Uuid {

View file

@ -39,9 +39,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);

View file

@ -35,9 +35,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);

View file

@ -35,9 +35,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);

View file

@ -33,9 +33,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);

View file

@ -21,9 +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 TotalEq for FailCmp {}
impl TotalOrd for FailCmp {
fn cmp(&self, _: &FailCmp) -> Ordering { fail!("cmp") }
@ -41,6 +39,5 @@ pub fn main() {
assert!(a != b);
assert!(a < b);
assert!(!a.equals(&b));
assert_eq!(a.cmp(&b), ::std::cmp::Less);
}

View file

@ -19,10 +19,6 @@ struct A<'a> {
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);