]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/needless_borrow.rs
split clippy into lints, plugin and cargo-clippy
[rust.git] / clippy_lints / src / needless_borrow.rs
1 //! Checks for needless address of operations (`&`)
2 //!
3 //! This lint is **warn** by default
4
5 use rustc::lint::*;
6 use rustc::hir::{ExprAddrOf, Expr, MutImmutable};
7 use rustc::ty::TyRef;
8 use utils::{span_lint, in_macro};
9 use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef;
10
11 /// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler
12 ///
13 /// **Why is this bad?** Suggests that the receiver of the expression borrows the expression
14 ///
15 /// **Known problems:**
16 ///
17 /// **Example:** `let x: &i32 = &&&&&&5;`
18 declare_lint! {
19     pub NEEDLESS_BORROW,
20     Warn,
21     "taking a reference that is going to be automatically dereferenced"
22 }
23
24 #[derive(Copy,Clone)]
25 pub struct NeedlessBorrow;
26
27 impl LintPass for NeedlessBorrow {
28     fn get_lints(&self) -> LintArray {
29         lint_array!(NEEDLESS_BORROW)
30     }
31 }
32
33 impl LateLintPass for NeedlessBorrow {
34     fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
35         if in_macro(cx, e.span) {
36             return;
37         }
38         if let ExprAddrOf(MutImmutable, ref inner) = e.node {
39             if let TyRef(..) = cx.tcx.expr_ty(inner).sty {
40                 if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
41                     if deref.autoderefs > 1 && deref.autoref.is_some() {
42                         span_lint(cx,
43                                   NEEDLESS_BORROW,
44                                   e.span,
45                                   "this expression borrows a reference that is immediately dereferenced by the compiler");
46                     }
47                 }
48             }
49         }
50     }
51 }