about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-19 21:19:29 +0000
committerbors <bors@rust-lang.org>2015-09-19 21:19:29 +0000
commit783c3fcc1ec19a804a63334d1945301fe89c52f6 (patch)
treed775ac4e2ee5b0a8d8c64786a6cef4d7b1407e32 /src/test
parent837840c61fce44da78096110ff83c91099a83da7 (diff)
parentf5569ecd7682a22f9ae3293a89479c7b99b6d941 (diff)
downloadrust-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')
-rw-r--r--src/test/auxiliary/augmented_assignments.rs22
-rw-r--r--src/test/compile-fail/assignment-operator-unimplemented.rs2
-rw-r--r--src/test/compile-fail/augmented-assignments-feature-gate-cross.rs25
-rw-r--r--src/test/compile-fail/augmented-assignments-feature-gate.rs26
-rw-r--r--src/test/compile-fail/augmented-assignments-trait.rs24
-rw-r--r--src/test/compile-fail/augmented-assignments.rs33
-rw-r--r--src/test/run-pass/augmented-assignments.rs164
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;
+        }
+    }
+}