diff options
| author | bors <bors@rust-lang.org> | 2014-12-15 22:11:44 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-15 22:11:44 +0000 |
| commit | 0669a432a2e09ad08886cb2138dbe9f5d681fb7f (patch) | |
| tree | 5183544df317d80a6bce406242596dd997e61b64 /src/libstd | |
| parent | 92e9e70d15bcf8d29890bf93793be402ad629229 (diff) | |
| parent | 89d2061c8f1cc2bcd5e9bb8a97e214f482d5ff2c (diff) | |
| download | rust-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.rs | 44 | ||||
| -rw-r--r-- | src/libstd/num/mod.rs | 24 | ||||
| -rw-r--r-- | src/libstd/time/duration.rs | 64 |
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, |
