]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/temporary_assignment.rs
Merge branch 'macro-use' into HEAD
[rust.git] / clippy_lints / src / temporary_assignment.rs
1 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
2 use rustc::{declare_lint, lint_array};
3 use rustc::hir::{Expr, ExprKind};
4 use crate::utils::is_adjusted;
5 use crate::utils::span_lint;
6
7 /// **What it does:** Checks for construction of a structure or tuple just to
8 /// assign a value in it.
9 ///
10 /// **Why is this bad?** Readability. If the structure is only created to be
11 /// updated, why not write the structure you want in the first place?
12 ///
13 /// **Known problems:** None.
14 ///
15 /// **Example:**
16 /// ```rust
17 /// (0, 0).0 = 1
18 /// ```
19 declare_clippy_lint! {
20     pub TEMPORARY_ASSIGNMENT,
21     complexity,
22     "assignments to temporaries"
23 }
24
25 fn is_temporary(expr: &Expr) -> bool {
26     match expr.node {
27         ExprKind::Struct(..) | ExprKind::Tup(..) => true,
28         _ => false,
29     }
30 }
31
32 #[derive(Copy, Clone)]
33 pub struct Pass;
34
35 impl LintPass for Pass {
36     fn get_lints(&self) -> LintArray {
37         lint_array!(TEMPORARY_ASSIGNMENT)
38     }
39 }
40
41 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
42     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
43         if let ExprKind::Assign(ref target, _) = expr.node {
44             if let ExprKind::Field(ref base, _) = target.node {
45                 if is_temporary(base) && !is_adjusted(cx, base) {
46                     span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary");
47                 }
48             }
49         }
50     }
51 }