فهرست منبع

update to latest rustc

Now, arithmetic binary operator traits take operands by value,
but non-copyable types such as `BigUint` should not always moved out when
applying operators.

This commit implements these operators not only for bare structs also
these references.
By-value implementations are forwarded to by-reference implementations
for now. In the future, by-value implementations may be replaced with
more efficient implementations (for example, the implementation that
reuses moved buffers.)
gifnksm 10 سال پیش
والد
کامیت
a325a566c6
7فایلهای تغییر یافته به همراه399 افزوده شده و 191 حذف شده
  1. 7 7
      benches/shootout-pidigits.rs
  2. 220 122
      src/bigint.rs
  3. 74 21
      src/complex.rs
  4. 13 3
      src/integer.rs
  5. 5 5
      src/iter.rs
  6. 4 4
      src/lib.rs
  7. 76 29
      src/rational.rs

+ 7 - 7
benches/shootout-pidigits.rs

@@ -70,24 +70,24 @@ impl Context {
     fn extract_digit(&self) -> int {
         if self.numer > self.accum {return -1;}
         let (q, r) =
-            (self.numer * Context::from_int(3) + self.accum)
+            (&self.numer * Context::from_int(3) + &self.accum)
             .div_rem(&self.denom);
-        if r + self.numer >= self.denom {return -1;}
+        if r + &self.numer >= self.denom {return -1;}
         q.to_int().unwrap()
     }
 
     fn next_term(&mut self, k: int) {
         let y2 = Context::from_int(k * 2 + 1);
-        self.accum = (self.accum + (self.numer << 1)) * y2;
-        self.numer = self.numer * Context::from_int(k);
-        self.denom = self.denom * y2;
+        self.accum = (&self.accum + (&self.numer << 1)) * &y2;
+        self.numer = &self.numer * Context::from_int(k);
+        self.denom = &self.denom * y2;
     }
 
     fn eliminate_digit(&mut self, d: int) {
         let d = Context::from_int(d);
         let ten = Context::from_int(10);
-        self.accum = (self.accum - self.denom * d) * ten;
-        self.numer = self.numer * ten;
+        self.accum = (&self.accum - &self.denom * d) * &ten;
+        self.numer = &self.numer * ten;
     }
 }
 

+ 220 - 122
src/bigint.rs

@@ -27,7 +27,7 @@
 //!     let mut f0: BigUint = Zero::zero();
 //!     let mut f1: BigUint = One::one();
 //!     for _ in range(0, n) {
-//!         let f2 = f0 + f1;
+//!         let f2 = f0 + &f1;
 //!         // This is a low cost way of swapping f0 with f1 and f1 with f2.
 //!         f0 = replace(&mut f1, f2);
 //!     }
@@ -183,14 +183,60 @@ impl FromStr for BigUint {
 
 impl Num for BigUint {}
 
-impl BitAnd<BigUint, BigUint> for BigUint {
-    fn bitand(&self, other: &BigUint) -> BigUint {
+macro_rules! forward_val_val_binop {
+    (impl $imp:ident for $res:ty, $method:ident) => {
+        impl $imp<$res, $res> for $res {
+            #[inline]
+            fn $method(self, other: $res) -> $res {
+                (&self).$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_ref_val_binop {
+    (impl $imp:ident for $res:ty, $method:ident) => {
+        impl<'a> $imp<$res, $res> for &'a $res {
+            #[inline]
+            fn $method(self, other: $res) -> $res {
+                self.$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_val_ref_binop {
+    (impl $imp:ident for $res:ty, $method:ident) => {
+        impl<'a> $imp<&'a $res, $res> for $res {
+            #[inline]
+            fn $method(self, other: &$res) -> $res {
+                (&self).$method(other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_all_binop {
+    (impl $imp:ident for $res:ty, $method:ident) => {
+        forward_val_val_binop!(impl $imp for $res, $method)
+        forward_ref_val_binop!(impl $imp for $res, $method)
+        forward_val_ref_binop!(impl $imp for $res, $method)
+    };
+}
+
+forward_all_binop!(impl BitAnd for BigUint, bitand)
+
+impl<'a, 'b> BitAnd<&'b BigUint, BigUint> for &'a BigUint {
+    #[inline]
+    fn bitand(self, other: &BigUint) -> BigUint {
         BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
     }
 }
 
-impl BitOr<BigUint, BigUint> for BigUint {
-    fn bitor(&self, other: &BigUint) -> BigUint {
+forward_all_binop!(impl BitOr for BigUint, bitor)
+
+impl<'a, 'b> BitOr<&'b BigUint, BigUint> for &'a BigUint {
+    fn bitor(self, other: &BigUint) -> BigUint {
         let zeros = ZERO_VEC.iter().cycle();
         let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
         let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
@@ -200,8 +246,10 @@ impl BitOr<BigUint, BigUint> for BigUint {
     }
 }
 
-impl BitXor<BigUint, BigUint> for BigUint {
-    fn bitxor(&self, other: &BigUint) -> BigUint {
+forward_all_binop!(impl BitXor for BigUint, bitxor)
+
+impl<'a, 'b> BitXor<&'b BigUint, BigUint> for &'a BigUint {
+    fn bitxor(self, other: &BigUint) -> BigUint {
         let zeros = ZERO_VEC.iter().cycle();
         let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
         let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
@@ -213,18 +261,28 @@ impl BitXor<BigUint, BigUint> for BigUint {
 
 impl Shl<uint, BigUint> for BigUint {
     #[inline]
-    fn shl(&self, rhs: &uint) -> BigUint {
-        let n_unit = *rhs / BigDigit::BITS;
-        let n_bits = *rhs % BigDigit::BITS;
+    fn shl(self, rhs: uint) -> BigUint { (&self) << rhs }
+}
+
+impl<'a> Shl<uint, BigUint> for &'a BigUint {
+    #[inline]
+    fn shl(self, rhs: uint) -> BigUint {
+        let n_unit = rhs / BigDigit::BITS;
+        let n_bits = rhs % BigDigit::BITS;
         return self.shl_unit(n_unit).shl_bits(n_bits);
     }
 }
 
 impl Shr<uint, BigUint> for BigUint {
     #[inline]
-    fn shr(&self, rhs: &uint) -> BigUint {
-        let n_unit = *rhs / BigDigit::BITS;
-        let n_bits = *rhs % BigDigit::BITS;
+    fn shr(self, rhs: uint) -> BigUint { (&self) >> rhs }
+}
+
+impl<'a> Shr<uint, BigUint> for &'a BigUint {
+    #[inline]
+    fn shr(self, rhs: uint) -> BigUint {
+        let n_unit = rhs / BigDigit::BITS;
+        let n_bits = rhs % BigDigit::BITS;
         return self.shr_unit(n_unit).shr_bits(n_bits);
     }
 }
@@ -244,8 +302,10 @@ impl One for BigUint {
 
 impl Unsigned for BigUint {}
 
-impl Add<BigUint, BigUint> for BigUint {
-    fn add(&self, other: &BigUint) -> BigUint {
+forward_all_binop!(impl Add for BigUint, add)
+
+impl<'a, 'b> Add<&'b BigUint, BigUint> for &'a BigUint {
+    fn add(self, other: &BigUint) -> BigUint {
         let zeros = ZERO_VEC.iter().cycle();
         let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
 
@@ -261,8 +321,10 @@ impl Add<BigUint, BigUint> for BigUint {
     }
 }
 
-impl Sub<BigUint, BigUint> for BigUint {
-    fn sub(&self, other: &BigUint) -> BigUint {
+forward_all_binop!(impl Sub for BigUint, sub)
+
+impl<'a, 'b> Sub<&'b BigUint, BigUint> for &'a BigUint {
+    fn sub(self, other: &BigUint) -> BigUint {
         let new_len = cmp::max(self.data.len(), other.data.len());
         let zeros = ZERO_VEC.iter().cycle();
         let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
@@ -289,8 +351,11 @@ impl Sub<BigUint, BigUint> for BigUint {
     }
 }
 
-impl Mul<BigUint, BigUint> for BigUint {
-    fn mul(&self, other: &BigUint) -> BigUint {
+
+forward_all_binop!(impl Mul for BigUint, mul)
+
+impl<'a, 'b> Mul<&'b BigUint, BigUint> for &'a BigUint {
+    fn mul(self, other: &BigUint) -> BigUint {
         if self.is_zero() || other.is_zero() { return Zero::zero(); }
 
         let (s_len, o_len) = (self.data.len(), other.data.len());
@@ -306,15 +371,15 @@ impl Mul<BigUint, BigUint> for BigUint {
         let (s_hi, s_lo) = cut_at(self,  half_len);
         let (o_hi, o_lo) = cut_at(other, half_len);
 
-        let ll = s_lo * o_lo;
-        let hh = s_hi * o_hi;
+        let ll = &s_lo * &o_lo;
+        let hh = &s_hi * &o_hi;
         let mm = {
             let (s1, n1) = sub_sign(s_hi, s_lo);
             let (s2, n2) = sub_sign(o_hi, o_lo);
             match (s1, s2) {
-                (Equal, _) | (_, Equal) => hh + ll,
-                (Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2),
-                (Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2)
+                (Equal, _) | (_, Equal) => &hh + &ll,
+                (Less, Greater) | (Greater, Less) => &hh + &ll + (n1 * n2),
+                (Less, Less) | (Greater, Greater) => &hh + &ll - (n1 * n2)
             }
         };
 
@@ -323,7 +388,7 @@ impl Mul<BigUint, BigUint> for BigUint {
 
         fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
             if n == 0 { return Zero::zero(); }
-            if n == 1 { return (*a).clone(); }
+            if n == 1 { return a.clone(); }
 
             let mut carry = 0;
             let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
@@ -355,17 +420,22 @@ impl Mul<BigUint, BigUint> for BigUint {
     }
 }
 
-impl Div<BigUint, BigUint> for BigUint {
+
+forward_all_binop!(impl Div for BigUint, div)
+
+impl<'a, 'b> Div<&'b BigUint, BigUint> for &'a BigUint {
     #[inline]
-    fn div(&self, other: &BigUint) -> BigUint {
+    fn div(self, other: &BigUint) -> BigUint {
         let (q, _) = self.div_rem(other);
         return q;
     }
 }
 
-impl Rem<BigUint, BigUint> for BigUint {
+forward_all_binop!(impl Rem for BigUint, rem)
+
+impl<'a, 'b> Rem<&'b BigUint, BigUint> for &'a BigUint {
     #[inline]
-    fn rem(&self, other: &BigUint) -> BigUint {
+    fn rem(self, other: &BigUint) -> BigUint {
         let (_, r) = self.div_rem(other);
         return r;
     }
@@ -446,7 +516,7 @@ impl Integer for BigUint {
             shift += 1;
         }
         assert!(shift < BigDigit::BITS);
-        let (d, m) = div_mod_floor_inner(*self << shift, *other << shift);
+        let (d, m) = div_mod_floor_inner(self << shift, other << shift);
         return (d, m >> shift);
 
 
@@ -457,14 +527,14 @@ impl Integer for BigUint {
             while m >= b {
                 let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
                 let mut d0 = d0;
-                let mut prod = b * d0;
+                let mut prod = &b * &d0;
                 while prod > m {
                     // FIXME(#5992): assignment operator overloads
-                    // d0 -= d_unit
-                    d0   = d0 - d_unit;
+                    // d0 -= &d_unit
+                    d0   = d0 - &d_unit;
                     // FIXME(#5992): assignment operator overloads
-                    // prod -= b_unit;
-                    prod = prod - b_unit
+                    // prod -= &b_unit;
+                    prod = prod - &b_unit
                 }
                 if d0.is_zero() {
                     n = 2;
@@ -522,7 +592,7 @@ impl Integer for BigUint {
         let mut n = (*other).clone();
         while !m.is_zero() {
             let temp = m;
-            m = n % temp;
+            m = n % &temp;
             n = temp;
         }
         return n;
@@ -530,16 +600,16 @@ impl Integer for BigUint {
 
     /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
     #[inline]
-    fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
+    fn lcm(&self, other: &BigUint) -> BigUint { ((self * other) / self.gcd(other)) }
 
     /// Deprecated, use `is_multiple_of` instead.
     #[deprecated = "function renamed to `is_multiple_of`"]
     #[inline]
-    fn divides(&self, other: &BigUint) -> bool { return self.is_multiple_of(other); }
+    fn divides(&self, other: &BigUint) -> bool { self.is_multiple_of(other) }
 
     /// Returns `true` if the number is a multiple of `other`.
     #[inline]
-    fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
+    fn is_multiple_of(&self, other: &BigUint) -> bool { (self % other).is_zero() }
 
     /// Returns `true` if the number is divisible by `2`.
     #[inline]
@@ -720,8 +790,8 @@ impl FromStrRadix for BigUint {
                     match d {
                         Some(d) => {
                             // FIXME(#5992): assignment operator overloads
-                            // n += d * power;
-                            n = n + d * power;
+                            // n += d * &power;
+                            n = n + d * &power;
                         }
                         None => { return None; }
                     }
@@ -733,8 +803,8 @@ impl FromStrRadix for BigUint {
             }
             end -= unit_len;
             // FIXME(#5992): assignment operator overloads
-            // power *= base_num;
-            power = power * base_num;
+            // power *= &base_num;
+            power = power * &base_num;
         }
     }
 }
@@ -938,15 +1008,25 @@ impl Num for BigInt {}
 
 impl Shl<uint, BigInt> for BigInt {
     #[inline]
-    fn shl(&self, rhs: &uint) -> BigInt {
-        BigInt::from_biguint(self.sign, self.data << *rhs)
+    fn shl(self, rhs: uint) -> BigInt { (&self) << rhs }
+}
+
+impl<'a> Shl<uint, BigInt> for &'a BigInt {
+    #[inline]
+    fn shl(self, rhs: uint) -> BigInt {
+        BigInt::from_biguint(self.sign, &self.data << rhs)
     }
 }
 
 impl Shr<uint, BigInt> for BigInt {
     #[inline]
-    fn shr(&self, rhs: &uint) -> BigInt {
-        BigInt::from_biguint(self.sign, self.data >> *rhs)
+    fn shr(self, rhs: uint) -> BigInt { (&self) >> rhs }
+}
+
+impl<'a> Shr<uint, BigInt> for &'a BigInt {
+    #[inline]
+    fn shr(self, rhs: uint) -> BigInt {
+        BigInt::from_biguint(self.sign, &self.data >> rhs)
     }
 }
 
@@ -978,7 +1058,7 @@ impl Signed for BigInt {
 
     #[inline]
     fn abs_sub(&self, other: &BigInt) -> BigInt {
-        if *self <= *other { Zero::zero() } else { *self - *other }
+        if *self <= *other { Zero::zero() } else { self - other }
     }
 
     #[inline]
@@ -997,64 +1077,74 @@ impl Signed for BigInt {
     fn is_negative(&self) -> bool { self.sign == Minus }
 }
 
-impl Add<BigInt, BigInt> for BigInt {
+forward_all_binop!(impl Add for BigInt, add)
+
+impl<'a, 'b> Add<&'b BigInt, BigInt> for &'a BigInt {
     #[inline]
-    fn add(&self, other: &BigInt) -> BigInt {
+    fn add(self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
-            (NoSign, _)      => other.clone(),
-            (_,    NoSign)   => self.clone(),
-            (Plus, Plus)   => BigInt::from_biguint(Plus, self.data + other.data),
-            (Plus, Minus)  => *self - (-*other),
-            (Minus, Plus)  => *other - (-*self),
+            (NoSign, _)    => other.clone(),
+            (_,    NoSign) => self.clone(),
+            (Plus, Plus)   => BigInt::from_biguint(Plus, &self.data + &other.data),
+            (Plus, Minus)  => self - (-*other),
+            (Minus, Plus)  => other - (-*self),
             (Minus, Minus) => -((-*self) + (-*other))
         }
     }
 }
 
-impl Sub<BigInt, BigInt> for BigInt {
+forward_all_binop!(impl Sub for BigInt, sub)
+
+impl<'a, 'b> Sub<&'b BigInt, BigInt> for &'a BigInt {
     #[inline]
-    fn sub(&self, other: &BigInt) -> BigInt {
+    fn sub(self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (NoSign, _)    => -*other,
             (_,    NoSign) => self.clone(),
             (Plus, Plus) => match self.data.cmp(&other.data) {
-                Less    => BigInt::from_biguint(Minus, other.data - self.data),
-                Greater => BigInt::from_biguint(Plus, self.data - other.data),
+                Less    => BigInt::from_biguint(Minus, &other.data - &self.data),
+                Greater => BigInt::from_biguint(Plus, &self.data - &other.data),
                 Equal   => Zero::zero()
             },
-            (Plus, Minus) => *self + (-*other),
-            (Minus, Plus) => -((-*self) + *other),
+            (Plus, Minus) => self + (-*other),
+            (Minus, Plus) => -((-*self) + other),
             (Minus, Minus) => (-*other) - (-*self)
         }
     }
 }
 
-impl Mul<BigInt, BigInt> for BigInt {
+forward_all_binop!(impl Mul for BigInt, mul)
+
+impl<'a, 'b> Mul<&'b BigInt, BigInt> for &'a BigInt {
     #[inline]
-    fn mul(&self, other: &BigInt) -> BigInt {
+    fn mul(self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (NoSign, _)     | (_,     NoSign)  => Zero::zero(),
             (Plus, Plus)  | (Minus, Minus) => {
-                BigInt::from_biguint(Plus, self.data * other.data)
+                BigInt::from_biguint(Plus, &self.data * &other.data)
             },
             (Plus, Minus) | (Minus, Plus) => {
-                BigInt::from_biguint(Minus, self.data * other.data)
+                BigInt::from_biguint(Minus, &self.data * &other.data)
             }
         }
     }
 }
 
-impl Div<BigInt, BigInt> for BigInt {
+forward_all_binop!(impl Div for BigInt, div)
+
+impl<'a, 'b> Div<&'b BigInt, BigInt> for &'a BigInt {
     #[inline]
-    fn div(&self, other: &BigInt) -> BigInt {
+    fn div(self, other: &BigInt) -> BigInt {
         let (q, _) = self.div_rem(other);
         q
     }
 }
 
-impl Rem<BigInt, BigInt> for BigInt {
+forward_all_binop!(impl Rem for BigInt, rem)
+
+impl<'a, 'b> Rem<&'b BigInt, BigInt> for &'a BigInt {
     #[inline]
-    fn rem(&self, other: &BigInt) -> BigInt {
+    fn rem(self, other: &BigInt) -> BigInt {
         let (_, r) = self.div_rem(other);
         r
     }
@@ -1131,19 +1221,24 @@ impl Integer for BigInt {
         let (d_ui, m_ui) = self.data.div_rem(&other.data);
         let d = BigInt::from_biguint(Plus, d_ui);
         let m = BigInt::from_biguint(Plus, m_ui);
+        let one: BigInt = One::one();
         match (self.sign, other.sign) {
             (_,    NoSign)   => panic!(),
             (Plus, Plus)  | (NoSign, Plus)  => (d, m),
-            (Plus, Minus) | (NoSign, Minus) => if m.is_zero() {
-                (-d, Zero::zero())
-            } else {
-                (-d - One::one(), m + *other)
-            },
-            (Minus, Plus) => if m.is_zero() {
-                (-d, Zero::zero())
-            } else {
-                (-d - One::one(), *other - m)
+            (Plus, Minus) | (NoSign, Minus) => {
+                if m.is_zero() {
+                    (-d, Zero::zero())
+                } else {
+                    (-d - one, m + other)
+                }
             },
+            (Minus, Plus) => {
+                if m.is_zero() {
+                    (-d, Zero::zero())
+                } else {
+                    (-d - one, other - m)
+                }
+            }
             (Minus, Minus) => (d, -m)
         }
     }
@@ -1374,7 +1469,7 @@ impl<R: Rng> RandBigInt for R {
                          ubound: &BigUint)
                          -> BigUint {
         assert!(*lbound < *ubound);
-        return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
+        return lbound + self.gen_biguint_below(&(ubound - lbound));
     }
 
     fn gen_bigint_range(&mut self,
@@ -1382,8 +1477,8 @@ impl<R: Rng> RandBigInt for R {
                         ubound: &BigInt)
                         -> BigInt {
         assert!(*lbound < *ubound);
-        let delta = (*ubound - *lbound).to_biguint().unwrap();
-        return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
+        let delta = (ubound - lbound).to_biguint().unwrap();
+        return lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
     }
 }
 
@@ -1912,8 +2007,8 @@ mod biguint_tests {
             let b = BigUint::from_slice(b_vec);
             let c = BigUint::from_slice(c_vec);
 
-            assert!(a + b == c);
-            assert!(b + a == c);
+            assert!(&a + &b == c);
+            assert!(&b + &a == c);
         }
     }
 
@@ -1925,8 +2020,8 @@ mod biguint_tests {
             let b = BigUint::from_slice(b_vec);
             let c = BigUint::from_slice(c_vec);
 
-            assert!(c - a == b);
-            assert!(c - b == a);
+            assert!(&c - &a == b);
+            assert!(&c - &b == a);
         }
     }
 
@@ -1983,8 +2078,8 @@ mod biguint_tests {
             let b = BigUint::from_slice(b_vec);
             let c = BigUint::from_slice(c_vec);
 
-            assert!(a * b == c);
-            assert!(b * a == c);
+            assert!(&a * &b == c);
+            assert!(&b * &a == c);
         }
 
         for elm in DIV_REM_QUADRUPLES.iter() {
@@ -1994,8 +2089,8 @@ mod biguint_tests {
             let c = BigUint::from_slice(c_vec);
             let d = BigUint::from_slice(d_vec);
 
-            assert!(a == b * c + d);
-            assert!(a == c * b + d);
+            assert!(a == &b * &c + &d);
+            assert!(a == &c * &b + &d);
         }
     }
 
@@ -2078,8 +2173,8 @@ mod biguint_tests {
             let c = BigUint::from_slice(c_vec);
             let d = BigUint::from_slice(d_vec);
 
-            assert!(a == b.checked_mul(&c).unwrap() + d);
-            assert!(a == c.checked_mul(&b).unwrap() + d);
+            assert!(a == b.checked_mul(&c).unwrap() + &d);
+            assert!(a == c.checked_mul(&b).unwrap() + &d);
         }
     }
 
@@ -2149,8 +2244,8 @@ mod biguint_tests {
         assert!(thousand.is_even());
         assert!(big.is_even());
         assert!(bigger.is_odd());
-        assert!((one << 64).is_even());
-        assert!(((one << 64) + one).is_odd());
+        assert!((&one << 64).is_even());
+        assert!(((&one << 64) + one).is_odd());
     }
 
     fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> {
@@ -2252,7 +2347,8 @@ mod biguint_tests {
             for i in range(2, n + 1) {
                 // FIXME(#5992): assignment operator overloads
                 // f *= FromPrimitive::from_uint(i);
-                f = f * FromPrimitive::from_uint(i).unwrap();
+                let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
+                f = f * bu;
             }
             return f;
         }
@@ -2513,14 +2609,14 @@ mod bigint_tests {
             let b = BigInt::from_slice(Plus, b_vec);
             let c = BigInt::from_slice(Plus, c_vec);
 
-            assert!(a + b == c);
-            assert!(b + a == c);
-            assert!(c + (-a) == b);
-            assert!(c + (-b) == a);
-            assert!(a + (-c) == (-b));
-            assert!(b + (-c) == (-a));
+            assert!(&a + &b == c);
+            assert!(&b + &a == c);
+            assert!(&c + (-a) == b);
+            assert!(&c + (-b) == a);
+            assert!(&a + (-c) == (-b));
+            assert!(&b + (-c) == (-a));
             assert!((-a) + (-b) == (-c))
-            assert!(a + (-a) == Zero::zero());
+            assert!(&a + (-a) == Zero::zero());
         }
     }
 
@@ -2532,14 +2628,14 @@ mod bigint_tests {
             let b = BigInt::from_slice(Plus, b_vec);
             let c = BigInt::from_slice(Plus, c_vec);
 
-            assert!(c - a == b);
-            assert!(c - b == a);
-            assert!((-b) - a == (-c))
-            assert!((-a) - b == (-c))
-            assert!(b - (-a) == c);
-            assert!(a - (-b) == c);
+            assert!(&c - &a == b);
+            assert!(&c - &b == a);
+            assert!((-b) - &a == (-c))
+            assert!((-a) - &b == (-c))
+            assert!(&b - (-a) == c);
+            assert!(&a - (-b) == c);
             assert!((-c) - (-a) == (-b));
-            assert!(a - a == Zero::zero());
+            assert!(&a - &a == Zero::zero());
         }
     }
 
@@ -2589,11 +2685,11 @@ mod bigint_tests {
             let b = BigInt::from_slice(Plus, b_vec);
             let c = BigInt::from_slice(Plus, c_vec);
 
-            assert!(a * b == c);
-            assert!(b * a == c);
+            assert!(&a * &b == c);
+            assert!(&b * &a == c);
 
-            assert!((-a) * b == -c);
-            assert!((-b) * a == -c);
+            assert!((-a) * &b == -c);
+            assert!((-b) * &a == -c);
         }
 
         for elm in DIV_REM_QUADRUPLES.iter() {
@@ -2603,8 +2699,8 @@ mod bigint_tests {
             let c = BigInt::from_slice(Plus, c_vec);
             let d = BigInt::from_slice(Plus, d_vec);
 
-            assert!(a == b * c + d);
-            assert!(a == c * b + d);
+            assert!(a == &b * &c + &d);
+            assert!(a == &c * &b + &d);
         }
     }
 
@@ -2616,7 +2712,7 @@ mod bigint_tests {
                 assert_eq!(m.sign, b.sign);
             }
             assert!(m.abs() <= b.abs());
-            assert!(*a == (*b) * d + m);
+            assert!(*a == b * &d + &m);
             assert!(d == *ans_d);
             assert!(m == *ans_m);
         }
@@ -2628,9 +2724,10 @@ mod bigint_tests {
                 check_sub(&a.neg(), b, &d.neg(), m);
                 check_sub(&a.neg(), &b.neg(), d, m);
             } else {
+                let one: BigInt = One::one();
                 check_sub(a, b, d, m);
-                check_sub(a, &b.neg(), &(d.neg() - One::one()), &(*m - *b));
-                check_sub(&a.neg(), b, &(d.neg() - One::one()), &(*b - *m));
+                check_sub(a, &b.neg(), &(d.neg() - &one), &(m - b));
+                check_sub(&a.neg(), b, &(d.neg() - &one), &(b - m));
                 check_sub(&a.neg(), &b.neg(), d, &m.neg());
             }
         }
@@ -2667,7 +2764,7 @@ mod bigint_tests {
                 assert_eq!(r.sign, a.sign);
             }
             assert!(r.abs() <= b.abs());
-            assert!(*a == (*b) * q + r);
+            assert!(*a == b * &q + &r);
             assert!(q == *ans_q);
             assert!(r == *ans_r);
         }
@@ -2761,8 +2858,8 @@ mod bigint_tests {
             let c = BigInt::from_slice(Plus, c_vec);
             let d = BigInt::from_slice(Plus, d_vec);
 
-            assert!(a == b.checked_mul(&c).unwrap() + d);
-            assert!(a == c.checked_mul(&b).unwrap() + d);
+            assert!(a == b.checked_mul(&c).unwrap() + &d);
+            assert!(a == c.checked_mul(&b).unwrap() + &d);
         }
     }
     #[test]
@@ -2943,7 +3040,8 @@ mod bench {
     fn factorial(n: uint) -> BigUint {
         let mut f: BigUint = One::one();
         for i in iter::range_inclusive(1, n) {
-            f = f * FromPrimitive::from_uint(i).unwrap();
+            let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
+            f = f * bu;
         }
         f
     }
@@ -2952,7 +3050,7 @@ mod bench {
         let mut f0: BigUint = Zero::zero();
         let mut f1: BigUint = One::one();
         for _ in range(0, n) {
-            let f2 = f0 + f1;
+            let f2 = f0 + &f1;
             f0 = replace(&mut f1, f2);
         }
         f0

+ 74 - 21
src/complex.rs

@@ -43,7 +43,7 @@ impl<T: Clone + Num> Complex<T> {
     /// have a sqrt function), i.e. `re^2 + im^2`.
     #[inline]
     pub fn norm_sqr(&self) -> T {
-        self.re * self.re + self.im * self.im
+        self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
     }
 
 
@@ -57,21 +57,21 @@ impl<T: Clone + Num> Complex<T> {
     /// Multiplies `self` by the scalar `t`.
     #[inline]
     pub fn scale(&self, t: T) -> Complex<T> {
-        Complex::new(self.re * t, self.im * t)
+        Complex::new(self.re.clone() * t.clone(), self.im.clone() * t)
     }
 
     /// Divides `self` by the scalar `t`.
     #[inline]
     pub fn unscale(&self, t: T) -> Complex<T> {
-        Complex::new(self.re / t, self.im / t)
+        Complex::new(self.re.clone() / t.clone(), self.im.clone() / t)
     }
 
     /// Returns `1/self`
     #[inline]
     pub fn inv(&self) -> Complex<T> {
         let norm_sqr = self.norm_sqr();
-        Complex::new(self.re / norm_sqr,
-                    -self.im / norm_sqr)
+        Complex::new(self.re.clone() / norm_sqr.clone(),
+                    -self.im.clone() / norm_sqr)
     }
 }
 
@@ -79,7 +79,7 @@ impl<T: Clone + FloatMath> Complex<T> {
     /// Calculate |self|
     #[inline]
     pub fn norm(&self) -> T {
-        self.re.hypot(self.im)
+        self.re.clone().hypot(self.im.clone())
     }
 }
 
@@ -87,7 +87,7 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
     /// Calculate the principal Arg of self.
     #[inline]
     pub fn arg(&self) -> T {
-        self.im.atan2(self.re)
+        self.im.clone().atan2(self.re.clone())
     }
     /// Convert to polar form (r, theta), such that `self = r * exp(i
     /// * theta)`
@@ -102,38 +102,91 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
     }
 }
 
+macro_rules! forward_val_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<T: Clone + Num> $imp<Complex<T>, Complex<T>> for Complex<T> {
+            #[inline]
+            fn $method(self, other: Complex<T>) -> Complex<T> {
+                (&self).$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_ref_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T: Clone + Num> $imp<Complex<T>, Complex<T>> for &'a Complex<T> {
+            #[inline]
+            fn $method(self, other: Complex<T>) -> Complex<T> {
+                self.$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_val_ref_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T: Clone + Num> $imp<&'a Complex<T>, Complex<T>> for Complex<T> {
+            #[inline]
+            fn $method(self, other: &Complex<T>) -> Complex<T> {
+                (&self).$method(other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_all_binop {
+    (impl $imp:ident, $method:ident) => {
+        forward_val_val_binop!(impl $imp, $method)
+        forward_ref_val_binop!(impl $imp, $method)
+        forward_val_ref_binop!(impl $imp, $method)
+    };
+}
+
 /* arithmetic */
+forward_all_binop!(impl Add, add)
+
 // (a + i b) + (c + i d) == (a + c) + i (b + d)
-impl<T: Clone + Num> Add<Complex<T>, Complex<T>> for Complex<T> {
+impl<'a, 'b, T: Clone + Num> Add<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
     #[inline]
-    fn add(&self, other: &Complex<T>) -> Complex<T> {
-        Complex::new(self.re + other.re, self.im + other.im)
+    fn add(self, other: &Complex<T>) -> Complex<T> {
+        Complex::new(self.re.clone() + other.re.clone(),
+                     self.im.clone() + other.im.clone())
     }
 }
+
+forward_all_binop!(impl Sub, sub)
+
 // (a + i b) - (c + i d) == (a - c) + i (b - d)
-impl<T: Clone + Num> Sub<Complex<T>, Complex<T>> for Complex<T> {
+impl<'a, 'b, T: Clone + Num> Sub<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
     #[inline]
-    fn sub(&self, other: &Complex<T>) -> Complex<T> {
-        Complex::new(self.re - other.re, self.im - other.im)
+    fn sub(self, other: &Complex<T>) -> Complex<T> {
+        Complex::new(self.re.clone() - other.re.clone(),
+                     self.im.clone() - other.im.clone())
     }
 }
+
+forward_all_binop!(impl Mul, mul)
+
 // (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
-impl<T: Clone + Num> Mul<Complex<T>, Complex<T>> for Complex<T> {
+impl<'a, 'b, T: Clone + Num> Mul<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
     #[inline]
-    fn mul(&self, other: &Complex<T>) -> Complex<T> {
-        Complex::new(self.re*other.re - self.im*other.im,
-                   self.re*other.im + self.im*other.re)
+    fn mul(self, other: &Complex<T>) -> Complex<T> {
+        Complex::new(self.re.clone() * other.re.clone() - self.im.clone() * other.im.clone(),
+                     self.re.clone() * other.im.clone() + self.im.clone() * other.re.clone())
     }
 }
 
+forward_all_binop!(impl Div, div)
+
 // (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
 //   == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
-impl<T: Clone + Num> Div<Complex<T>, Complex<T>> for Complex<T> {
+impl<'a, 'b, T: Clone + Num> Div<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
     #[inline]
-    fn div(&self, other: &Complex<T>) -> Complex<T> {
+    fn div(self, other: &Complex<T>) -> Complex<T> {
         let norm_sqr = other.norm_sqr();
-        Complex::new((self.re*other.re + self.im*other.im) / norm_sqr,
-                   (self.im*other.re - self.re*other.im) / norm_sqr)
+        Complex::new((self.re.clone() * other.re.clone() + self.im.clone() * other.im.clone()) / norm_sqr.clone(),
+                     (self.im.clone() * other.re.clone() - self.re.clone() * other.im.clone()) / norm_sqr)
     }
 }
 

+ 13 - 3
src/integer.rs

@@ -134,9 +134,7 @@ pub trait Integer: Num + PartialOrd
     /// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
     /// ~~~
     #[inline]
-    fn div_rem(&self, other: &Self) -> (Self, Self) {
-        (*self / *other, *self % *other)
-    }
+    fn div_rem(&self, other: &Self) -> (Self, Self);
 
     /// Simultaneous floored integer division and modulus.
     /// Returns `(quotient, remainder)`.
@@ -253,6 +251,12 @@ macro_rules! impl_integer_for_int {
             /// Returns `true` if the number is not divisible by `2`
             #[inline]
             fn is_odd(&self) -> bool { !self.is_even() }
+
+            /// Simultaneous truncated integer division and modulus.
+            #[inline]
+            fn div_rem(&self, other: &$T) -> ($T, $T) {
+                (*self / *other, *self % *other)
+            }
         }
 
         #[cfg(test)]
@@ -425,6 +429,12 @@ macro_rules! impl_integer_for_uint {
             /// Returns `true` if the number is not divisible by `2`.
             #[inline]
             fn is_odd(&self) -> bool { !(*self).is_even() }
+
+            /// Simultaneous truncated integer division and modulus.
+            #[inline]
+            fn div_rem(&self, other: &$T) -> ($T, $T) {
+                (*self / *other, *self % *other)
+            }
         }
 
         #[cfg(test)]

+ 5 - 5
src/iter.rs

@@ -45,7 +45,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
     fn next(&mut self) -> Option<A> {
         if self.state < self.stop {
             let result = self.state.clone();
-            self.state = self.state + self.one;
+            self.state = self.state.clone() + self.one.clone();
             Some(result)
         } else {
             None
@@ -91,7 +91,7 @@ impl<A: Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator<A> for R
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         if self.stop > self.state {
-            self.stop = self.stop - self.one;
+            self.stop = self.stop.clone() - self.one.clone();
             Some(self.stop.clone())
         } else {
             None
@@ -151,7 +151,7 @@ impl<A: Sub<A, A> + Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedItera
     fn next_back(&mut self) -> Option<A> {
         if self.range.stop > self.range.state {
             let result = self.range.stop.clone();
-            self.range.stop = self.range.stop - self.range.one;
+            self.range.stop = self.range.stop.clone() - self.range.one.clone();
             Some(result)
         } else if !self.done && self.range.state == self.range.stop {
             self.done = true;
@@ -246,7 +246,7 @@ mod tests {
         }
 
         impl Add<Foo, Foo> for Foo {
-            fn add(&self, _: &Foo) -> Foo {
+            fn add(self, _: Foo) -> Foo {
                 Foo
             }
         }
@@ -270,7 +270,7 @@ mod tests {
         }
 
         impl Mul<Foo, Foo> for Foo {
-            fn mul(&self, _: &Foo) -> Foo {
+            fn mul(self, _: Foo) -> Foo {
                 Foo
             }
         }

+ 4 - 4
src/lib.rs

@@ -28,7 +28,7 @@
 //!     let mut approx = start.clone();
 //!
 //!     for _ in range(0, iterations) {
-//!         approx = (approx + (start / approx)) /
+//!         approx = (&approx + (&start / &approx)) /
 //!             Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
 //!     }
 //!
@@ -123,15 +123,15 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
 /// assert_eq!(num::pow(2i, 4), 16);
 /// ```
 #[inline]
-pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
+pub fn pow<T: Clone + One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
     if exp == 1 { base }
     else {
         let mut acc = one::<T>();
         while exp > 0 {
             if (exp & 1) == 1 {
-                acc = acc * base;
+                acc = acc * base.clone();
             }
-            base = base * base;
+            base = base.clone() * base;
             exp = exp >> 1;
         }
         acc

+ 76 - 29
src/rational.rs

@@ -92,10 +92,10 @@ impl<T: Clone + Integer + PartialOrd>
 
         // FIXME(#5992): assignment operator overloads
         // self.numer /= g;
-        self.numer = self.numer / g;
+        self.numer = self.numer.clone() / g.clone();
         // FIXME(#5992): assignment operator overloads
         // self.denom /= g;
-        self.denom = self.denom / g;
+        self.denom = self.denom.clone() / g;
 
         // keep denom positive!
         if self.denom < Zero::zero() {
@@ -121,9 +121,10 @@ impl<T: Clone + Integer + PartialOrd>
     #[inline]
     pub fn floor(&self) -> Ratio<T> {
         if *self < Zero::zero() {
-            Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
+            let one: T = One::one();
+            Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) / self.denom.clone())
         } else {
-            Ratio::from_integer(self.numer / self.denom)
+            Ratio::from_integer(self.numer.clone() / self.denom.clone())
         }
     }
 
@@ -131,9 +132,10 @@ impl<T: Clone + Integer + PartialOrd>
     #[inline]
     pub fn ceil(&self) -> Ratio<T> {
         if *self < Zero::zero() {
-            Ratio::from_integer(self.numer / self.denom)
+            Ratio::from_integer(self.numer.clone() / self.denom.clone())
         } else {
-            Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
+            let one: T = One::one();
+            Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) / self.denom.clone())
         }
     }
 
@@ -141,7 +143,7 @@ impl<T: Clone + Integer + PartialOrd>
     #[inline]
     pub fn round(&self) -> Ratio<T> {
         let one: T = One::one();
-        let two: T = one + one;
+        let two: T = one.clone() + one.clone();
 
         // Find unsigned fractional part of rational number
         let fractional = self.fract().abs();
@@ -150,16 +152,17 @@ impl<T: Clone + Integer + PartialOrd>
         // is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
         // a >= (b/2)+1. This avoids overflow issues.
         let half_or_larger = if fractional.denom().is_even() {
-            *fractional.numer() >= *fractional.denom() / two
+            *fractional.numer() >= fractional.denom().clone() / two.clone()
         } else {
-            *fractional.numer() >= (*fractional.denom() / two) + one
+            *fractional.numer() >= (fractional.denom().clone() / two.clone()) + one.clone()
         };
 
         if half_or_larger {
+            let one: Ratio<T> = One::one();
             if *self >= Zero::zero() {
-                self.trunc() + One::one()
+                self.trunc() + one
             } else {
-                self.trunc() - One::one()
+                self.trunc() - one
             }
         } else {
             self.trunc()
@@ -169,13 +172,13 @@ impl<T: Clone + Integer + PartialOrd>
     /// Rounds towards zero.
     #[inline]
     pub fn trunc(&self) -> Ratio<T> {
-        Ratio::from_integer(self.numer / self.denom)
+        Ratio::from_integer(self.numer.clone() / self.denom.clone())
     }
 
     /// Returns the fractional part of a number.
     #[inline]
     pub fn fract(&self) -> Ratio<T> {
-        Ratio::new_raw(self.numer % self.denom, self.denom.clone())
+        Ratio::new_raw(self.numer.clone() % self.denom.clone(), self.denom.clone())
     }
 }
 
@@ -212,11 +215,11 @@ macro_rules! cmp_impl {
     };
     // return something other than a Ratio<T>
     (impl $imp:ident, $($method:ident -> $res:ty),*) => {
-        impl<T: Mul<T,T> + $imp> $imp for Ratio<T> {
+        impl<T: Clone + 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))
+                    (self.numer.clone() * other.denom.clone()). $method (&(self.denom.clone()*other.numer.clone()))
                 }
             )*
         }
@@ -228,34 +231,78 @@ cmp_impl!(impl PartialOrd, lt -> bool, gt -> bool, le -> bool, ge -> bool,
 cmp_impl!(impl Eq, )
 cmp_impl!(impl Ord, cmp -> cmp::Ordering)
 
+macro_rules! forward_val_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for Ratio<T> {
+            #[inline]
+            fn $method(self, other: Ratio<T>) -> Ratio<T> {
+                (&self).$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_ref_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for &'a Ratio<T> {
+            #[inline]
+            fn $method(self, other: Ratio<T>) -> Ratio<T> {
+                self.$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_val_ref_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T: Clone + Integer + PartialOrd> $imp<&'a Ratio<T>, Ratio<T>> for Ratio<T> {
+            #[inline]
+            fn $method(self, other: &Ratio<T>) -> Ratio<T> {
+                (&self).$method(other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_all_binop {
+    (impl $imp:ident, $method:ident) => {
+        forward_val_val_binop!(impl $imp, $method)
+        forward_ref_val_binop!(impl $imp, $method)
+        forward_val_ref_binop!(impl $imp, $method)
+    };
+}
+
 /* Arithmetic */
+forward_all_binop!(impl Mul, mul)
 // a/b * c/d = (a*c)/(b*d)
-impl<T: Clone + Integer + PartialOrd>
-    Mul<Ratio<T>,Ratio<T>> for Ratio<T> {
+impl<'a, 'b, T: Clone + Integer + PartialOrd>
+    Mul<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
     #[inline]
-    fn mul(&self, rhs: &Ratio<T>) -> Ratio<T> {
-        Ratio::new(self.numer * rhs.numer, self.denom * rhs.denom)
+    fn mul(self, rhs: &Ratio<T>) -> Ratio<T> {
+        Ratio::new(self.numer.clone() * rhs.numer.clone(), self.denom.clone() * rhs.denom.clone())
     }
 }
 
+forward_all_binop!(impl Div, div)
 // (a/b) / (c/d) = (a*d)/(b*c)
-impl<T: Clone + Integer + PartialOrd>
-    Div<Ratio<T>,Ratio<T>> for Ratio<T> {
+impl<'a, 'b, T: Clone + Integer + PartialOrd>
+    Div<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
     #[inline]
-    fn div(&self, rhs: &Ratio<T>) -> Ratio<T> {
-        Ratio::new(self.numer * rhs.denom, self.denom * rhs.numer)
+    fn div(self, rhs: &Ratio<T>) -> Ratio<T> {
+        Ratio::new(self.numer.clone() * rhs.denom.clone(), self.denom.clone() * rhs.numer.clone())
     }
 }
 
 // Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
 macro_rules! arith_impl {
     (impl $imp:ident, $method:ident) => {
-        impl<T: Clone + Integer + PartialOrd>
-            $imp<Ratio<T>,Ratio<T>> for Ratio<T> {
+        forward_all_binop!(impl $imp, $method)
+        impl<'a, 'b, T: Clone + Integer + PartialOrd>
+            $imp<&'b Ratio<T>,Ratio<T>> for &'a Ratio<T> {
             #[inline]
-            fn $method(&self, rhs: &Ratio<T>) -> Ratio<T> {
-                Ratio::new((self.numer * rhs.denom).$method(&(self.denom * rhs.numer)),
-                           self.denom * rhs.denom)
+            fn $method(self, rhs: &Ratio<T>) -> Ratio<T> {
+                Ratio::new((self.numer.clone() * rhs.denom.clone()).$method(self.denom.clone() * rhs.numer.clone()),
+                           self.denom.clone() * rhs.denom.clone())
             }
         }
     }
@@ -312,7 +359,7 @@ impl<T: Clone + Integer + PartialOrd>
 
     #[inline]
     fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
-        if *self <= *other { Zero::zero() } else { *self - *other }
+        if *self <= *other { Zero::zero() } else { self - other }
     }
 
     #[inline]