From eed9ec15fb2f38f4ea315f0a112f726d5623264f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 11 Feb 2016 13:50:41 +0100 Subject: [PATCH] improve the `no_effect` lint --- src/no_effect.rs | 27 ++++++++++++--- .../absurd-extreme-comparisons.rs | 2 +- tests/compile-fail/array_indexing.rs | 1 + tests/compile-fail/bit_masks.rs | 4 +-- tests/compile-fail/cast.rs | 1 + tests/compile-fail/cmp_nan.rs | 2 +- tests/compile-fail/copies.rs | 2 +- tests/compile-fail/eq_op.rs | 1 + tests/compile-fail/eta.rs | 2 +- tests/compile-fail/float_cmp.rs | 2 +- tests/compile-fail/identity_op.rs | 2 +- tests/compile-fail/modulo_one.rs | 1 + tests/compile-fail/mut_mut.rs | 2 +- tests/compile-fail/no_effect.rs | 33 ++++++++++++++++++- 14 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/no_effect.rs b/src/no_effect.rs index e1067f27ab9..0df5ede82da 100644 --- a/src/no_effect.rs +++ b/src/no_effect.rs @@ -1,6 +1,6 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::middle::def::Def; -use rustc_front::hir::{Expr, ExprCall, ExprLit, ExprPath, ExprStruct}; +use rustc_front::hir::{Expr, Expr_}; use rustc_front::hir::{Stmt, StmtSemi}; use utils::in_macro; @@ -24,16 +24,33 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool { return false; } match expr.node { - ExprLit(..) | - ExprPath(..) => true, - ExprStruct(_, ref fields, ref base) => { + Expr_::ExprLit(..) | + Expr_::ExprClosure(..) | + Expr_::ExprRange(None, None) | + Expr_::ExprPath(..) => true, + Expr_::ExprIndex(ref a, ref b) | + Expr_::ExprRange(Some(ref a), Some(ref b)) | + Expr_::ExprBinary(_, ref a, ref b) => has_no_effect(cx, a) && has_no_effect(cx, b), + Expr_::ExprVec(ref v) | + Expr_::ExprTup(ref v) => v.iter().all(|val| has_no_effect(cx, val)), + Expr_::ExprRange(Some(ref inner), None) | + Expr_::ExprRange(None, Some(ref inner)) | + Expr_::ExprRepeat(ref inner, _) | + Expr_::ExprCast(ref inner, _) | + Expr_::ExprType(ref inner, _) | + Expr_::ExprUnary(_, ref inner) | + Expr_::ExprField(ref inner, _) | + Expr_::ExprTupField(ref inner, _) | + Expr_::ExprAddrOf(_, ref inner) | + Expr_::ExprBox(ref inner) => has_no_effect(cx, inner), + Expr_::ExprStruct(_, ref fields, ref base) => { fields.iter().all(|field| has_no_effect(cx, &field.expr)) && match *base { Some(ref base) => has_no_effect(cx, base), None => true, } } - ExprCall(ref callee, ref args) => { + Expr_::ExprCall(ref callee, ref args) => { let def = cx.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()); match def { Some(Def::Struct(..)) | diff --git a/tests/compile-fail/absurd-extreme-comparisons.rs b/tests/compile-fail/absurd-extreme-comparisons.rs index 9718225d203..7e2ad1fede5 100644 --- a/tests/compile-fail/absurd-extreme-comparisons.rs +++ b/tests/compile-fail/absurd-extreme-comparisons.rs @@ -2,7 +2,7 @@ #![plugin(clippy)] #![deny(absurd_extreme_comparisons)] -#![allow(unused, eq_op)] +#![allow(unused, eq_op, no_effect)] fn main() { const Z: u32 = 0; diff --git a/tests/compile-fail/array_indexing.rs b/tests/compile-fail/array_indexing.rs index 68ab71da586..1d9492bc0ab 100644 --- a/tests/compile-fail/array_indexing.rs +++ b/tests/compile-fail/array_indexing.rs @@ -2,6 +2,7 @@ #![plugin(clippy)] #![deny(out_of_bounds_indexing)] +#![allow(no_effect)] fn main() { let x = [1,2,3,4]; diff --git a/tests/compile-fail/bit_masks.rs b/tests/compile-fail/bit_masks.rs index f78012864a0..98135295862 100644 --- a/tests/compile-fail/bit_masks.rs +++ b/tests/compile-fail/bit_masks.rs @@ -5,7 +5,7 @@ const THREE_BITS : i64 = 7; const EVEN_MORE_REDIRECTION : i64 = THREE_BITS; #[deny(bad_bit_mask)] -#[allow(ineffective_bit_mask, identity_op)] +#[allow(ineffective_bit_mask, identity_op, no_effect)] fn main() { let x = 5; @@ -45,7 +45,7 @@ fn main() { } #[deny(ineffective_bit_mask)] -#[allow(bad_bit_mask)] +#[allow(bad_bit_mask, no_effect)] fn ineffective() { let x = 5; diff --git a/tests/compile-fail/cast.rs b/tests/compile-fail/cast.rs index 70cc1919be4..0f44fa2c1fd 100644 --- a/tests/compile-fail/cast.rs +++ b/tests/compile-fail/cast.rs @@ -2,6 +2,7 @@ #![plugin(clippy)] #[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)] +#[allow(no_effect)] fn main() { // Test cast_precision_loss 1i32 as f32; //~ERROR casting i32 to f32 causes a loss of precision (i32 is 32 bits wide, but f32's mantissa is only 23 bits wide) diff --git a/tests/compile-fail/cmp_nan.rs b/tests/compile-fail/cmp_nan.rs index b2369e164ff..d2188130a61 100644 --- a/tests/compile-fail/cmp_nan.rs +++ b/tests/compile-fail/cmp_nan.rs @@ -2,7 +2,7 @@ #![plugin(clippy)] #[deny(cmp_nan)] -#[allow(float_cmp)] +#[allow(float_cmp, no_effect)] fn main() { let x = 5f32; x == std::f32::NAN; //~ERROR doomed comparison with NAN diff --git a/tests/compile-fail/copies.rs b/tests/compile-fail/copies.rs index 0f57b619ccc..d6e666f299b 100755 --- a/tests/compile-fail/copies.rs +++ b/tests/compile-fail/copies.rs @@ -1,7 +1,7 @@ #![feature(plugin)] #![plugin(clippy)] -#![allow(dead_code)] +#![allow(dead_code, no_effect)] #![allow(let_and_return)] #![allow(needless_return)] #![allow(unused_variables)] diff --git a/tests/compile-fail/eq_op.rs b/tests/compile-fail/eq_op.rs index 7be5ef11ce6..487185516bf 100644 --- a/tests/compile-fail/eq_op.rs +++ b/tests/compile-fail/eq_op.rs @@ -3,6 +3,7 @@ #[deny(eq_op)] #[allow(identity_op)] +#[allow(no_effect)] fn main() { // simple values and comparisons 1 == 1; //~ERROR equal expressions diff --git a/tests/compile-fail/eta.rs b/tests/compile-fail/eta.rs index 1ffca9ac5ce..46680f2b8d8 100644 --- a/tests/compile-fail/eta.rs +++ b/tests/compile-fail/eta.rs @@ -1,6 +1,6 @@ #![feature(plugin)] #![plugin(clippy)] -#![allow(unknown_lints, unused)] +#![allow(unknown_lints, unused, no_effect)] #![deny(redundant_closure)] fn main() { diff --git a/tests/compile-fail/float_cmp.rs b/tests/compile-fail/float_cmp.rs index 27cde245f68..d1ecb37cdd5 100644 --- a/tests/compile-fail/float_cmp.rs +++ b/tests/compile-fail/float_cmp.rs @@ -2,7 +2,7 @@ #![plugin(clippy)] #![deny(float_cmp)] -#![allow(unused)] +#![allow(unused, no_effect)] use std::ops::Add; diff --git a/tests/compile-fail/identity_op.rs b/tests/compile-fail/identity_op.rs index c1141e0b460..28873ee6b73 100644 --- a/tests/compile-fail/identity_op.rs +++ b/tests/compile-fail/identity_op.rs @@ -5,7 +5,7 @@ const ONE : i64 = 1; const NEG_ONE : i64 = -1; const ZERO : i64 = 0; -#[allow(eq_op)] +#[allow(eq_op, no_effect)] #[deny(identity_op)] fn main() { let x = 0; diff --git a/tests/compile-fail/modulo_one.rs b/tests/compile-fail/modulo_one.rs index 1301b4e499c..e84209a6d1e 100644 --- a/tests/compile-fail/modulo_one.rs +++ b/tests/compile-fail/modulo_one.rs @@ -1,6 +1,7 @@ #![feature(plugin)] #![plugin(clippy)] #![deny(modulo_one)] +#![allow(no_effect)] fn main() { 10 % 1; //~ERROR any number modulo 1 will be 0 diff --git a/tests/compile-fail/mut_mut.rs b/tests/compile-fail/mut_mut.rs index 2560a54c0ef..0db9cb3bdef 100644 --- a/tests/compile-fail/mut_mut.rs +++ b/tests/compile-fail/mut_mut.rs @@ -1,7 +1,7 @@ #![feature(plugin)] #![plugin(clippy)] -#![allow(unused)] +#![allow(unused, no_effect)] //#![plugin(regex_macros)] //extern crate regex; diff --git a/tests/compile-fail/no_effect.rs b/tests/compile-fail/no_effect.rs index 21118b82718..52ea423a57d 100644 --- a/tests/compile-fail/no_effect.rs +++ b/tests/compile-fail/no_effect.rs @@ -1,4 +1,4 @@ -#![feature(plugin)] +#![feature(plugin, box_syntax)] #![plugin(clippy)] #![deny(no_effect)] @@ -20,14 +20,32 @@ fn get_struct() -> Struct { Struct { field: 0 } } fn main() { let s = get_struct(); + let s2 = get_struct(); 0; //~ERROR statement with no effect + s2; //~ERROR statement with no effect Unit; //~ERROR statement with no effect Tuple(0); //~ERROR statement with no effect Struct { field: 0 }; //~ERROR statement with no effect Struct { ..s }; //~ERROR statement with no effect Enum::Tuple(0); //~ERROR statement with no effect Enum::Struct { field: 0 }; //~ERROR statement with no effect + 5 + 6; //~ERROR statement with no effect + *&42; //~ERROR statement with no effect + &6; //~ERROR statement with no effect + (5, 6, 7); //~ERROR statement with no effect + box 42; //~ERROR statement with no effect + ..; //~ERROR statement with no effect + 5..; //~ERROR statement with no effect + ..5; //~ERROR statement with no effect + 5..6; //~ERROR statement with no effect + [42, 55]; //~ERROR statement with no effect + [42, 55][1]; //~ERROR statement with no effect + (42, 55).1; //~ERROR statement with no effect + [42; 55]; //~ERROR statement with no effect + [42; 55][13]; //~ERROR statement with no effect + let mut x = 0; + || x += 5; //~ERROR statement with no effect // Do not warn get_number(); @@ -36,4 +54,17 @@ fn main() { Struct { ..get_struct() }; Enum::Tuple(get_number()); Enum::Struct { field: get_number() }; + 5 + get_number(); + *&get_number(); + &get_number(); + (5, 6, get_number()); + box get_number(); + get_number()..; + ..get_number(); + 5..get_number(); + [42, get_number()]; + [42, 55][get_number() as usize]; + (42, get_number()).1; + [get_number(); 55]; + [42; 55][get_number() as usize]; }