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.
This commit is contained in:
Ulrik Sverdrup 2016-03-04 21:01:59 +01:00
parent c97524bef9
commit a03222c2b1
2 changed files with 21 additions and 1 deletions

View file

@ -1415,7 +1415,9 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
}
hir::ExprAssignOp(_, ref l, _) => {
if !this.ir.tcx.is_method_call(expr.id) {
this.check_lvalue(&l);
}
intravisit::walk_expr(this, expr);
}

View file

@ -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;
}
}
}