]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/needless_borrow.rs
Improve docs
[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
12 /// dereferenced immediately by the compiler
13 ///
14 /// **Why is this bad?** Suggests that the receiver of the expression borrows the expression.
15 ///
16 /// **Known problems:**
17 ///
18 /// **Example:**
19 /// ```rust
20 /// let x: &i32 = &&&&&&5;
21 /// ```
22 declare_lint! {
23     pub NEEDLESS_BORROW,
24     Warn,
25     "taking a reference that is going to be automatically dereferenced"
26 }
27
28 #[derive(Copy,Clone)]
29 pub struct NeedlessBorrow;
30
31 impl LintPass for NeedlessBorrow {
32     fn get_lints(&self) -> LintArray {
33         lint_array!(NEEDLESS_BORROW)
34     }
35 }
36
37 impl LateLintPass for NeedlessBorrow {
38     fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
39         if in_macro(cx, e.span) {
40             return;
41         }
42         if let ExprAddrOf(MutImmutable, ref inner) = e.node {
43             if let TyRef(..) = cx.tcx.expr_ty(inner).sty {
44                 if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
45                     if deref.autoderefs > 1 && deref.autoref.is_some() {
46                         span_lint(cx,
47                                   NEEDLESS_BORROW,
48                                   e.span,
49                                   "this expression borrows a reference that is immediately dereferenced by the \
50                                    compiler");
51                     }
52                 }
53             }
54         }
55     }
56 }