about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-06 15:10:44 +0000
committerbors <bors@rust-lang.org>2016-03-06 15:10:44 +0000
commit71f4658c14c63be2c9e6dbf85e46c10cf20fed71 (patch)
tree3735bc58e00addda52b6f5ffc4193a85a54151c1 /src/test
parent80922a7ad8dfc2a774233a190d36f895d655a83c (diff)
parentcfe4efd0523cd8106b20ba732f7d7677548f8157 (diff)
Auto merge of #32048 - bluss:overloaded-assign-op, r=eddyb
Do not trigger unused_assignments for overloaded AssignOps

If `v` were a type with some kind of indirection, so that `v += 1` would
have an effect even if `v` were not used anymore, the unused_assignments lint
would mark a false positive.

This exempts overloaded (non-primitive) assign ops from being treated as
assignments (they are method calls).

The previous compile-fail tests that ensure x += 1 can trigger for
primitive types continue to pass. Added a representative test for the
"view" indirection.

Fixes #31895
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/liveness-unused.rs46
-rw-r--r--src/test/run-pass/augmented-assignments.rs18
2 files changed, 64 insertions, 0 deletions
diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs
index 0fee48a8c6c..3aab953eb79 100644
--- a/src/test/compile-fail/liveness-unused.rs
+++ b/src/test/compile-fail/liveness-unused.rs
@@ -12,6 +12,8 @@
 #![deny(unused_assignments)]
 #![allow(dead_code, non_camel_case_types, trivial_numeric_casts)]
 
+use std::ops::AddAssign;
+
 fn f1(x: isize) {
     //~^ ERROR unused variable: `x`
 }
@@ -100,5 +102,49 @@ fn f5c() {
     }
 }
 
+struct View<'a>(&'a mut [i32]);
+
+impl<'a> AddAssign<i32> for View<'a> {
+    fn add_assign(&mut self, rhs: i32) {
+        for lhs in self.0.iter_mut() {
+            *lhs += rhs;
+        }
+    }
+}
+
+fn f6() {
+    let mut array = [1, 2, 3];
+    let mut v = View(&mut array);
+
+    // ensure an error shows up for x even if lhs of an overloaded add assign
+
+    let x;
+    //~^ ERROR variable `x` is assigned to, but never used
+
+    *({
+        x = 0;  //~ ERROR value assigned to `x` is never read
+        &mut v
+    }) += 1;
+}
+
+
+struct MutRef<'a>(&'a mut i32);
+
+impl<'a> AddAssign<i32> for MutRef<'a> {
+    fn add_assign(&mut self, rhs: i32) {
+        *self.0 += rhs;
+    }
+}
+
+fn f7() {
+    let mut a = 1;
+    {
+        // `b` does not trigger unused_variables
+        let mut b = MutRef(&mut a);
+        b += 1;
+    }
+    drop(a);
+}
+
 fn main() {
 }
diff --git a/src/test/run-pass/augmented-assignments.rs b/src/test/run-pass/augmented-assignments.rs
index 8c9ebcd274a..3ed9e8548dc 100644
--- a/src/test/run-pass/augmented-assignments.rs
+++ b/src/test/run-pass/augmented-assignments.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![deny(unused_assignments)]
+
 use std::mem;
 use std::ops::{
     AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, Index, MulAssign, RemAssign,
@@ -27,6 +29,8 @@ impl Slice {
     }
 }
 
+struct View<'a>(&'a mut [i32]);
+
 fn main() {
     let mut x = Int(1);
 
@@ -78,6 +82,12 @@ fn main() {
     assert_eq!(array[0], 1);
     assert_eq!(array[1], 2);
     assert_eq!(array[2], 3);
+
+    // sized indirection
+    // check that this does *not* trigger the unused_assignments lint
+    let mut array = [0, 1, 2];
+    let mut view = View(&mut array);
+    view += 1;
 }
 
 impl AddAssign for Int {
@@ -159,3 +169,11 @@ impl AddAssign<i32> for Slice {
         }
     }
 }
+
+impl<'a> AddAssign<i32> for View<'a> {
+    fn add_assign(&mut self, rhs: i32) {
+        for lhs in self.0.iter_mut() {
+            *lhs += rhs;
+        }
+    }
+}