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