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