]> git.lizzy.rs Git - rust.git/blob - src/no_effect.rs
Remove * dep
[rust.git] / src / no_effect.rs
1 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
2 use rustc::middle::def::{DefStruct, DefVariant};
3 use rustc_front::hir::{Expr, ExprCall, ExprLit, ExprPath, ExprStruct};
4 use rustc_front::hir::{Stmt, StmtSemi};
5
6 use utils::in_macro;
7 use utils::span_lint;
8
9 /// **What it does:** This lint `Warn`s on statements which have no effect.
10 ///
11 /// **Why is this bad?** Similar to dead code, these statements are actually executed. However, as they have no effect, all they do is make the code less readable.
12 ///
13 /// **Known problems:** None.
14 ///
15 /// **Example:** `0;`
16 declare_lint! {
17     pub NO_EFFECT,
18     Warn,
19     "statements with no effect"
20 }
21
22 fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
23     if in_macro(cx, expr.span) {
24         return false;
25     }
26     match expr.node {
27         ExprLit(..) |
28         ExprPath(..) => true,
29         ExprStruct(_, ref fields, ref base) => {
30             fields.iter().all(|field| has_no_effect(cx, &field.expr)) &&
31             match *base {
32                 Some(ref base) => has_no_effect(cx, base),
33                 None => true,
34             }
35         }
36         ExprCall(ref callee, ref args) => {
37             let def = cx.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
38             match def {
39                 Some(DefStruct(..)) |
40                 Some(DefVariant(..)) => {
41                     args.iter().all(|arg| has_no_effect(cx, arg))
42                 }
43                 _ => false,
44             }
45         }
46         _ => false,
47     }
48 }
49
50 #[derive(Copy, Clone)]
51 pub struct NoEffectPass;
52
53 impl LintPass for NoEffectPass {
54     fn get_lints(&self) -> LintArray {
55         lint_array!(NO_EFFECT)
56     }
57 }
58
59 impl LateLintPass for NoEffectPass {
60     fn check_stmt(&mut self, cx: &LateContext, stmt: &Stmt) {
61         if let StmtSemi(ref expr, _) = stmt.node {
62             if has_no_effect(cx, expr) {
63                 span_lint(cx, NO_EFFECT, stmt.span,
64                           "statement with no effect");
65             }
66         }
67     }
68 }