diff options
| author | bors <bors@rust-lang.org> | 2015-09-19 21:19:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-09-19 21:19:29 +0000 |
| commit | 783c3fcc1ec19a804a63334d1945301fe89c52f6 (patch) | |
| tree | d775ac4e2ee5b0a8d8c64786a6cef4d7b1407e32 /src/test | |
| parent | 837840c61fce44da78096110ff83c91099a83da7 (diff) | |
| parent | f5569ecd7682a22f9ae3293a89479c7b99b6d941 (diff) | |
| download | rust-783c3fcc1ec19a804a63334d1945301fe89c52f6.tar.gz rust-783c3fcc1ec19a804a63334d1945301fe89c52f6.zip | |
Auto merge of #28345 - japaric:op-assign, r=nmatsakis
Implements overload-able augmented/compound assignments, like `a += b` via the `AddAssign` trait, as specified in RFC [953] [953]: https://github.com/rust-lang/rfcs/blob/master/text/0953-op-assign.md r? @nikomatsakis
Diffstat (limited to 'src/test')
7 files changed, 295 insertions, 1 deletions
diff --git a/src/test/auxiliary/augmented_assignments.rs b/src/test/auxiliary/augmented_assignments.rs new file mode 100644 index 00000000000..9577e1ff0c7 --- /dev/null +++ b/src/test/auxiliary/augmented_assignments.rs @@ -0,0 +1,22 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(augmented_assignments)] +#![feature(op_assign_traits)] + +use std::ops::AddAssign; + +pub struct Int(i32); + +impl AddAssign<i32> for Int { + fn add_assign(&mut self, _: i32) { + unimplemented!(); + } +} diff --git a/src/test/compile-fail/assignment-operator-unimplemented.rs b/src/test/compile-fail/assignment-operator-unimplemented.rs index fef27af5957..5b24c6bd79f 100644 --- a/src/test/compile-fail/assignment-operator-unimplemented.rs +++ b/src/test/compile-fail/assignment-operator-unimplemented.rs @@ -13,5 +13,5 @@ struct Foo; fn main() { let mut a = Foo; let ref b = Foo; - a += *b; //~ Error: binary assignment operation `+=` cannot be applied to types `Foo` and `Foo` + a += *b; //~ Error: binary assignment operation `+=` cannot be applied to type `Foo` } diff --git a/src/test/compile-fail/augmented-assignments-feature-gate-cross.rs b/src/test/compile-fail/augmented-assignments-feature-gate-cross.rs new file mode 100644 index 00000000000..0aca9a5c7ee --- /dev/null +++ b/src/test/compile-fail/augmented-assignments-feature-gate-cross.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:augmented_assignments.rs + +// Test that the feature gate is needed when using augmented assignments that were overloaded in +// another crate + +extern crate augmented_assignments; + +use augmented_assignments::Int; + +fn main() { + let mut x = Int(0); + x += 1; + //~^ error: overloaded augmented assignments are not stable + // | help: add #![feature(augmented_assignments)] to the crate features to enable +} diff --git a/src/test/compile-fail/augmented-assignments-feature-gate.rs b/src/test/compile-fail/augmented-assignments-feature-gate.rs new file mode 100644 index 00000000000..66c3014c7a9 --- /dev/null +++ b/src/test/compile-fail/augmented-assignments-feature-gate.rs @@ -0,0 +1,26 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::AddAssign; + +struct Int(i32); + +impl AddAssign<i32> for Int { + fn add_assign(&mut self, _: i32) { + unimplemented!() + } +} + +fn main() { + let mut x = Int(0); + x += 1; + //~^ error: overloaded augmented assignments are not stable + // | help: add #![feature(augmented_assignments)] to the crate features to enable +} diff --git a/src/test/compile-fail/augmented-assignments-trait.rs b/src/test/compile-fail/augmented-assignments-trait.rs new file mode 100644 index 00000000000..83e8d1f3b38 --- /dev/null +++ b/src/test/compile-fail/augmented-assignments-trait.rs @@ -0,0 +1,24 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::AddAssign; +//~^ error: use of unstable library feature 'op_assign_traits' + +struct Int(i32); + +impl AddAssign for Int { + //~^ error: use of unstable library feature 'op_assign_traits' + fn add_assign(&mut self, _: Int) { + //~^ error: use of unstable library feature 'op_assign_traits' + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/compile-fail/augmented-assignments.rs b/src/test/compile-fail/augmented-assignments.rs new file mode 100644 index 00000000000..ee64171fd8c --- /dev/null +++ b/src/test/compile-fail/augmented-assignments.rs @@ -0,0 +1,33 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(augmented_assignments)] + +use std::ops::AddAssign; + +struct Int(i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: Int) { + unimplemented!() + } +} + +fn main() { + let mut x = Int(1); + x //~ error: use of moved value: `x` + += + x; //~ note: `x` moved here because it has type `Int`, which is non-copyable + + let y = Int(2); + y //~ error: cannot borrow immutable local variable `y` as mutable + += + Int(1); +} diff --git a/src/test/run-pass/augmented-assignments.rs b/src/test/run-pass/augmented-assignments.rs new file mode 100644 index 00000000000..eb4c1dbb0b7 --- /dev/null +++ b/src/test/run-pass/augmented-assignments.rs @@ -0,0 +1,164 @@ +// Copyright 2015 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(augmented_assignments)] +#![feature(op_assign_traits)] + +use std::mem; +use std::ops::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, Index, MulAssign, RemAssign, + ShlAssign, ShrAssign, SubAssign, +}; + +#[derive(Debug, PartialEq)] +struct Int(i32); + +struct Slice([i32]); + +impl Slice { + fn new(slice: &mut [i32]) -> &mut Slice { + unsafe { + mem::transmute(slice) + } + } +} + +fn main() { + let mut x = Int(1); + + x += Int(2); + assert_eq!(x, Int(0b11)); + + x &= Int(0b01); + assert_eq!(x, Int(0b01)); + + x |= Int(0b10); + assert_eq!(x, Int(0b11)); + + x ^= Int(0b01); + assert_eq!(x, Int(0b10)); + + x /= Int(2); + assert_eq!(x, Int(1)); + + x *= Int(3); + assert_eq!(x, Int(3)); + + x %= Int(2); + assert_eq!(x, Int(1)); + + // overloaded RHS + x <<= 1u8; + assert_eq!(x, Int(2)); + + x <<= 1u16; + assert_eq!(x, Int(4)); + + x >>= 1u8; + assert_eq!(x, Int(2)); + + x >>= 1u16; + assert_eq!(x, Int(1)); + + x -= Int(1); + assert_eq!(x, Int(0)); + + // indexed LHS + let mut v = vec![Int(1), Int(2)]; + v[0] += Int(2); + assert_eq!(v[0], Int(3)); + + // unsized RHS + let mut array = [0, 1, 2]; + *Slice::new(&mut array) += 1; + assert_eq!(array[0], 1); + assert_eq!(array[1], 2); + assert_eq!(array[2], 3); +} + +impl AddAssign for Int { + fn add_assign(&mut self, rhs: Int) { + self.0 += rhs.0; + } +} + +impl BitAndAssign for Int { + fn bitand_assign(&mut self, rhs: Int) { + self.0 &= rhs.0; + } +} + +impl BitOrAssign for Int { + fn bitor_assign(&mut self, rhs: Int) { + self.0 |= rhs.0; + } +} + +impl BitXorAssign for Int { + fn bitxor_assign(&mut self, rhs: Int) { + self.0 ^= rhs.0; + } +} + +impl DivAssign for Int { + fn div_assign(&mut self, rhs: Int) { + self.0 /= rhs.0; + } +} + +impl MulAssign for Int { + fn mul_assign(&mut self, rhs: Int) { + self.0 *= rhs.0; + } +} + +impl RemAssign for Int { + fn rem_assign(&mut self, rhs: Int) { + self.0 %= rhs.0; + } +} + +impl ShlAssign<u8> for Int { + fn shl_assign(&mut self, rhs: u8) { + self.0 <<= rhs; + } +} + +impl ShlAssign<u16> for Int { + fn shl_assign(&mut self, rhs: u16) { + self.0 <<= rhs; + } +} + +impl ShrAssign<u8> for Int { + fn shr_assign(&mut self, rhs: u8) { + self.0 >>= rhs; + } +} + +impl ShrAssign<u16> for Int { + fn shr_assign(&mut self, rhs: u16) { + self.0 >>= rhs; + } +} + +impl SubAssign for Int { + fn sub_assign(&mut self, rhs: Int) { + self.0 -= rhs.0; + } +} + +impl AddAssign<i32> for Slice { + fn add_assign(&mut self, rhs: i32) { + for lhs in &mut self.0 { + *lhs += rhs; + } + } +} |
