about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-15 22:11:44 +0000
committerbors <bors@rust-lang.org>2014-12-15 22:11:44 +0000
commit0669a432a2e09ad08886cb2138dbe9f5d681fb7f (patch)
tree5183544df317d80a6bce406242596dd997e61b64 /src/libstd
parent92e9e70d15bcf8d29890bf93793be402ad629229 (diff)
parent89d2061c8f1cc2bcd5e9bb8a97e214f482d5ff2c (diff)
downloadrust-0669a432a2e09ad08886cb2138dbe9f5d681fb7f.tar.gz
rust-0669a432a2e09ad08886cb2138dbe9f5d681fb7f.zip
auto merge of #19448 : japaric/rust/binops-by-value, r=nikomatsakis
- The following operator traits now take their arguments by value: `Add`, `Sub`, `Mul`, `Div`, `Rem`, `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`. This breaks all existing implementations of these traits.

- The binary operation `a OP b` now "desugars" to `OpTrait::op_method(a, b)` and consumes both arguments.

- `String` and `Vec` addition have been changed to reuse the LHS owned value, and to avoid internal cloning. Only the following asymmetric operations are available: `String + &str` and `Vec<T> + &[T]`, which are now a short-hand for the "append" operation.

[breaking-change]

---

This passes `make check` locally. I haven't touch the unary operators in this PR, but converting them to by value should be very similar to this PR. I can work on them after this gets the thumbs up.

@nikomatsakis r? the compiler changes
@aturon r? the library changes. I think the only controversial bit is the semantic change of the `Vec`/`String` `Add` implementation.
cc #19148 
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/bitflags.rs44
-rw-r--r--src/libstd/num/mod.rs24
-rw-r--r--src/libstd/time/duration.rs64
3 files changed, 121 insertions, 11 deletions
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index 8a6d329ec46..2be6f5057a1 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -205,6 +205,8 @@ macro_rules! bitflags {
             }
         }
 
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the union of the two sets of flags.
             #[inline]
@@ -213,6 +215,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the union of the two sets of flags.
+            #[inline]
+            fn bitor(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits | other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the left flags, but with all the right flags toggled.
             #[inline]
@@ -221,6 +234,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the left flags, but with all the right flags toggled.
+            #[inline]
+            fn bitxor(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits ^ other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the intersection between the two sets of flags.
             #[inline]
@@ -229,6 +253,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the intersection between the two sets of flags.
+            #[inline]
+            fn bitand(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits & other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl Sub<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the set difference of the two sets of flags.
             #[inline]
@@ -237,6 +272,15 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the set difference of the two sets of flags.
+            #[inline]
+            fn sub(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits & !other.bits }
+            }
+        }
+
         impl Not<$BitFlags> for $BitFlags {
             /// Returns the complement of this set of flags.
             #[inline]
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index a15e71b4a2a..9aaaceb87e6 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -19,6 +19,7 @@
 #[cfg(test)] use cmp::PartialEq;
 #[cfg(test)] use fmt::Show;
 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
+#[cfg(test)] use kinds::Copy;
 
 pub use core::num::{Num, div_rem, Zero, zero, One, one};
 pub use core::num::{Unsigned, pow, Bounded};
@@ -130,18 +131,19 @@ pub fn test_num<T>(ten: T, two: T) where
      + Add<T, T> + Sub<T, T>
      + Mul<T, T> + Div<T, T>
      + Rem<T, T> + Show
+     + Copy
 {
-    assert_eq!(ten.add(&two),  cast(12i).unwrap());
-    assert_eq!(ten.sub(&two),  cast(8i).unwrap());
-    assert_eq!(ten.mul(&two),  cast(20i).unwrap());
-    assert_eq!(ten.div(&two),  cast(5i).unwrap());
-    assert_eq!(ten.rem(&two),  cast(0i).unwrap());
-
-    assert_eq!(ten.add(&two),  ten + two);
-    assert_eq!(ten.sub(&two),  ten - two);
-    assert_eq!(ten.mul(&two),  ten * two);
-    assert_eq!(ten.div(&two),  ten / two);
-    assert_eq!(ten.rem(&two),  ten % two);
+    assert_eq!(ten.add(two),  cast(12i).unwrap());
+    assert_eq!(ten.sub(two),  cast(8i).unwrap());
+    assert_eq!(ten.mul(two),  cast(20i).unwrap());
+    assert_eq!(ten.div(two),  cast(5i).unwrap());
+    assert_eq!(ten.rem(two),  cast(0i).unwrap());
+
+    assert_eq!(ten.add(two),  ten + two);
+    assert_eq!(ten.sub(two),  ten - two);
+    assert_eq!(ten.mul(two),  ten * two);
+    assert_eq!(ten.div(two),  ten / two);
+    assert_eq!(ten.rem(two),  ten % two);
 }
 
 #[cfg(test)]
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 34a3d6aa275..f98cebd9675 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -276,6 +276,8 @@ impl Neg<Duration> for Duration {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<Duration,Duration> for Duration {
     fn add(&self, rhs: &Duration) -> Duration {
         let mut secs = self.secs + rhs.secs;
@@ -288,6 +290,21 @@ impl Add<Duration,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<Duration, Duration> for Duration {
+    fn add(self, rhs: Duration) -> Duration {
+        let mut secs = self.secs + rhs.secs;
+        let mut nanos = self.nanos + rhs.nanos;
+        if nanos >= NANOS_PER_SEC {
+            nanos -= NANOS_PER_SEC;
+            secs += 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Sub<Duration,Duration> for Duration {
     fn sub(&self, rhs: &Duration) -> Duration {
         let mut secs = self.secs - rhs.secs;
@@ -300,6 +317,21 @@ impl Sub<Duration,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Sub<Duration, Duration> for Duration {
+    fn sub(self, rhs: Duration) -> Duration {
+        let mut secs = self.secs - rhs.secs;
+        let mut nanos = self.nanos - rhs.nanos;
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Mul<i32,Duration> for Duration {
     fn mul(&self, rhs: &i32) -> Duration {
         // Multiply nanoseconds as i64, because it cannot overflow that way.
@@ -310,6 +342,19 @@ impl Mul<i32,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Mul<i32, Duration> for Duration {
+    fn mul(self, rhs: i32) -> Duration {
+        // Multiply nanoseconds as i64, because it cannot overflow that way.
+        let total_nanos = self.nanos as i64 * rhs as i64;
+        let (extra_secs, nanos) = div_mod_floor_64(total_nanos, NANOS_PER_SEC as i64);
+        let secs = self.secs * rhs as i64 + extra_secs;
+        Duration { secs: secs, nanos: nanos as i32 }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Div<i32,Duration> for Duration {
     fn div(&self, rhs: &i32) -> Duration {
         let mut secs = self.secs / *rhs as i64;
@@ -328,6 +373,25 @@ impl Div<i32,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Div<i32, Duration> for Duration {
+    fn div(self, rhs: i32) -> Duration {
+        let mut secs = self.secs / rhs as i64;
+        let carry = self.secs - secs * rhs as i64;
+        let extra_nanos = carry * NANOS_PER_SEC as i64 / rhs as i64;
+        let mut nanos = self.nanos / rhs + extra_nanos as i32;
+        if nanos >= NANOS_PER_SEC {
+            nanos -= NANOS_PER_SEC;
+            secs += 1;
+        }
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
 impl fmt::Show for Duration {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         // technically speaking, negative duration is not valid ISO 8601,