]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/reference.rs
97ee9b2a577558768f9fa937eceb6db87275b63c
[rust.git] / clippy_lints / src / reference.rs
1 use rustc::hir::*;
2 use rustc::lint::*;
3 use utils::{span_lint_and_then, snippet};
4
5 /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
6 ///
7 /// **Why is this bad?** Immediately dereferencing a reference is no-op and
8 /// makes the code less clear.
9 ///
10 /// **Known problems:** Multiple dereference/addrof pairs are not handled so
11 /// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
12 ///
13 /// **Example:**
14 /// ```rust
15 /// let a = f(*&mut b);
16 /// let c = *&d;
17 /// ```
18 declare_lint! {
19     pub DEREF_ADDROF,
20     Warn,
21     "use of `*&` or `*&mut` in an expression"
22 }
23
24 pub struct Pass;
25
26 impl LintPass for Pass {
27     fn get_lints(&self) -> LintArray {
28         lint_array!(DEREF_ADDROF)
29     }
30 }
31
32 impl LateLintPass for Pass {
33     fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
34         if let ExprUnary(UnDeref, ref deref_target) = e.node {
35             if let ExprAddrOf(_, ref addrof_target) = deref_target.node {
36                 span_lint_and_then(
37                     cx,
38                     DEREF_ADDROF,
39                     e.span,
40                     "immediately dereferencing a reference",
41                     |db| {
42                         db.span_suggestion(e.span, "try this",
43                                              format!("{}", snippet(cx, addrof_target.span, "_")));
44                     });
45             }
46         }
47     }
48 }