]>
Commit | Line | Data |
---|---|---|
cdc7bbd5 XL |
1 | use clippy_utils::diagnostics::span_lint; |
2 | use clippy_utils::is_adjusted; | |
f20569fa XL |
3 | use rustc_hir::{Expr, ExprKind}; |
4 | use rustc_lint::{LateContext, LateLintPass}; | |
5 | use rustc_session::{declare_lint_pass, declare_tool_lint}; | |
6 | ||
7 | declare_clippy_lint! { | |
94222f64 XL |
8 | /// ### What it does |
9 | /// Checks for construction of a structure or tuple just to | |
f20569fa XL |
10 | /// assign a value in it. |
11 | /// | |
94222f64 XL |
12 | /// ### Why is this bad? |
13 | /// Readability. If the structure is only created to be | |
f20569fa XL |
14 | /// updated, why not write the structure you want in the first place? |
15 | /// | |
94222f64 | 16 | /// ### Example |
f20569fa XL |
17 | /// ```rust |
18 | /// (0, 0).0 = 1 | |
19 | /// ``` | |
a2a8927a | 20 | #[clippy::version = "pre 1.29.0"] |
f20569fa XL |
21 | pub TEMPORARY_ASSIGNMENT, |
22 | complexity, | |
23 | "assignments to temporaries" | |
24 | } | |
25 | ||
26 | fn is_temporary(expr: &Expr<'_>) -> bool { | |
27 | matches!(&expr.kind, ExprKind::Struct(..) | ExprKind::Tup(..)) | |
28 | } | |
29 | ||
30 | declare_lint_pass!(TemporaryAssignment => [TEMPORARY_ASSIGNMENT]); | |
31 | ||
32 | impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment { | |
33 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { | |
34 | if let ExprKind::Assign(target, ..) = &expr.kind { | |
35 | let mut base = target; | |
36 | while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind { | |
37 | base = f; | |
38 | } | |
39 | if is_temporary(base) && !is_adjusted(cx, base) { | |
40 | span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary"); | |
41 | } | |
42 | } | |
43 | } | |
44 | } |