]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use crate::utils::{eq_expr_value, snippet, span_lint}; |
2 | use rustc_hir::{Expr, ExprKind}; | |
3 | use rustc_lint::{LateContext, LateLintPass}; | |
4 | use rustc_session::{declare_lint_pass, declare_tool_lint}; | |
5 | ||
6 | declare_clippy_lint! { | |
7 | /// **What it does:** Checks for explicit self-assignments. | |
8 | /// | |
9 | /// **Why is this bad?** Self-assignments are redundant and unlikely to be | |
10 | /// intentional. | |
11 | /// | |
12 | /// **Known problems:** If expression contains any deref coercions or | |
13 | /// indexing operations they are assumed not to have any side effects. | |
14 | /// | |
15 | /// **Example:** | |
16 | /// | |
17 | /// ```rust | |
18 | /// struct Event { | |
19 | /// id: usize, | |
20 | /// x: i32, | |
21 | /// y: i32, | |
22 | /// } | |
23 | /// | |
24 | /// fn copy_position(a: &mut Event, b: &Event) { | |
25 | /// a.x = b.x; | |
26 | /// a.y = a.y; | |
27 | /// } | |
28 | /// ``` | |
29 | pub SELF_ASSIGNMENT, | |
30 | correctness, | |
31 | "explicit self-assignment" | |
32 | } | |
33 | ||
34 | declare_lint_pass!(SelfAssignment => [SELF_ASSIGNMENT]); | |
35 | ||
36 | impl<'tcx> LateLintPass<'tcx> for SelfAssignment { | |
37 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { | |
38 | if let ExprKind::Assign(lhs, rhs, _) = &expr.kind { | |
39 | if eq_expr_value(cx, lhs, rhs) { | |
40 | let lhs = snippet(cx, lhs.span, "<lhs>"); | |
41 | let rhs = snippet(cx, rhs.span, "<rhs>"); | |
42 | span_lint( | |
43 | cx, | |
44 | SELF_ASSIGNMENT, | |
45 | expr.span, | |
46 | &format!("self-assignment of `{}` to `{}`", rhs, lhs), | |
47 | ); | |
48 | } | |
49 | } | |
50 | } | |
51 | } |