diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs index b8aac47202cf..27acdd7c726e 100644 --- a/clippy_lints/src/lib.register_all.rs +++ b/clippy_lints/src/lib.register_all.rs @@ -261,6 +261,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(operators::MODULO_ONE), LintId::of(operators::OP_REF), LintId::of(operators::PTR_EQ), + LintId::of(operators::SELF_ASSIGNMENT), LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP), LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL), LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL), @@ -286,7 +287,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(repeat_once::REPEAT_ONCE), LintId::of(returns::LET_AND_RETURN), LintId::of(returns::NEEDLESS_RETURN), - LintId::of(self_assignment::SELF_ASSIGNMENT), LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS), LintId::of(serde_api::SERDE_API_MISUSE), LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs index 7133b6cdd88f..7d5e65cb27a1 100644 --- a/clippy_lints/src/lib.register_correctness.rs +++ b/clippy_lints/src/lib.register_correctness.rs @@ -51,13 +51,13 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve LintId::of(operators::ERASING_OP), LintId::of(operators::INEFFECTIVE_BIT_MASK), LintId::of(operators::MODULO_ONE), + LintId::of(operators::SELF_ASSIGNMENT), LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP), LintId::of(ptr::INVALID_NULL_PTR_USAGE), LintId::of(ptr::MUT_FROM_REF), LintId::of(ranges::REVERSED_EMPTY_RANGES), LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC), LintId::of(regex::INVALID_REGEX), - LintId::of(self_assignment::SELF_ASSIGNMENT), LintId::of(serde_api::SERDE_API_MISUSE), LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT), LintId::of(swap::ALMOST_SWAPPED), diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs index 408f2857263c..af7226f242f3 100644 --- a/clippy_lints/src/lib.register_lints.rs +++ b/clippy_lints/src/lib.register_lints.rs @@ -437,6 +437,7 @@ store.register_lints(&[ operators::NEEDLESS_BITWISE_BOOL, operators::OP_REF, operators::PTR_EQ, + operators::SELF_ASSIGNMENT, operators::VERBOSE_BIT_MASK, option_env_unwrap::OPTION_ENV_UNWRAP, option_if_let_else::OPTION_IF_LET_ELSE, @@ -483,7 +484,6 @@ store.register_lints(&[ returns::LET_AND_RETURN, returns::NEEDLESS_RETURN, same_name_method::SAME_NAME_METHOD, - self_assignment::SELF_ASSIGNMENT, self_named_constructors::SELF_NAMED_CONSTRUCTORS, semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED, serde_api::SERDE_API_MISUSE, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 7b618831ae0a..172fdf8c8526 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -355,7 +355,6 @@ mod repeat_once; mod return_self_not_must_use; mod returns; mod same_name_method; -mod self_assignment; mod self_named_constructors; mod semicolon_if_nothing_returned; mod serde_api; @@ -829,7 +828,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| Box::new(stable_sort_primitive::StableSortPrimitive)); store.register_late_pass(|| Box::new(repeat_once::RepeatOnce)); store.register_late_pass(|| Box::new(unwrap_in_result::UnwrapInResult)); - store.register_late_pass(|| Box::new(self_assignment::SelfAssignment)); store.register_late_pass(|| Box::new(manual_ok_or::ManualOkOr)); store.register_late_pass(|| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned)); store.register_late_pass(|| Box::new(async_yields_async::AsyncYieldsAsync)); diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index b2cf1660ae0c..35fe405bcf14 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -22,6 +22,7 @@ mod needless_bitwise_bool; mod numeric_arithmetic; mod op_ref; mod ptr_eq; +mod self_assignment; mod verbose_bit_mask; declare_clippy_lint! { @@ -701,6 +702,45 @@ declare_clippy_lint! { "use `std::ptr::eq` when comparing raw pointers" } +declare_clippy_lint! { + /// ### What it does + /// Checks for explicit self-assignments. + /// + /// ### Why is this bad? + /// Self-assignments are redundant and unlikely to be + /// intentional. + /// + /// ### Known problems + /// If expression contains any deref coercions or + /// indexing operations they are assumed not to have any side effects. + /// + /// ### Example + /// ```rust + /// struct Event { + /// x: i32, + /// } + /// + /// fn copy_position(a: &mut Event, b: &Event) { + /// a.x = a.x; + /// } + /// ``` + /// + /// Should be: + /// ```rust + /// struct Event { + /// x: i32, + /// } + /// + /// fn copy_position(a: &mut Event, b: &Event) { + /// a.x = b.x; + /// } + /// ``` + #[clippy::version = "1.48.0"] + pub SELF_ASSIGNMENT, + correctness, + "explicit self-assignment" +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, @@ -730,6 +770,7 @@ impl_lint_pass!(Operators => [ MODULO_ARITHMETIC, NEEDLESS_BITWISE_BOOL, PTR_EQ, + SELF_ASSIGNMENT, ]); impl Operators { pub fn new(verbose_bit_mask_threshold: u64) -> Self { @@ -775,6 +816,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { }, ExprKind::Assign(lhs, rhs, _) => { assign_op_pattern::check(cx, e, lhs, rhs); + self_assignment::check(cx, e, lhs, rhs); }, ExprKind::Unary(op, arg) => { if op == UnOp::Neg { diff --git a/clippy_lints/src/operators/self_assignment.rs b/clippy_lints/src/operators/self_assignment.rs new file mode 100644 index 000000000000..9d6bec05bf09 --- /dev/null +++ b/clippy_lints/src/operators/self_assignment.rs @@ -0,0 +1,20 @@ +use clippy_utils::diagnostics::span_lint; +use clippy_utils::eq_expr_value; +use clippy_utils::source::snippet; +use rustc_hir::Expr; +use rustc_lint::LateContext; + +use super::SELF_ASSIGNMENT; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>) { + if eq_expr_value(cx, lhs, rhs) { + let lhs = snippet(cx, lhs.span, ""); + let rhs = snippet(cx, rhs.span, ""); + span_lint( + cx, + SELF_ASSIGNMENT, + e.span, + &format!("self-assignment of `{}` to `{}`", rhs, lhs), + ); + } +} diff --git a/clippy_lints/src/self_assignment.rs b/clippy_lints/src/self_assignment.rs deleted file mode 100644 index af7f5c9b681b..000000000000 --- a/clippy_lints/src/self_assignment.rs +++ /dev/null @@ -1,64 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use clippy_utils::eq_expr_value; -use clippy_utils::source::snippet; -use rustc_hir::{Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; - -declare_clippy_lint! { - /// ### What it does - /// Checks for explicit self-assignments. - /// - /// ### Why is this bad? - /// Self-assignments are redundant and unlikely to be - /// intentional. - /// - /// ### Known problems - /// If expression contains any deref coercions or - /// indexing operations they are assumed not to have any side effects. - /// - /// ### Example - /// ```rust - /// struct Event { - /// x: i32, - /// } - /// - /// fn copy_position(a: &mut Event, b: &Event) { - /// a.x = a.x; - /// } - /// ``` - /// - /// Should be: - /// ```rust - /// struct Event { - /// x: i32, - /// } - /// - /// fn copy_position(a: &mut Event, b: &Event) { - /// a.x = b.x; - /// } - /// ``` - #[clippy::version = "1.48.0"] - pub SELF_ASSIGNMENT, - correctness, - "explicit self-assignment" -} - -declare_lint_pass!(SelfAssignment => [SELF_ASSIGNMENT]); - -impl<'tcx> LateLintPass<'tcx> for SelfAssignment { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::Assign(lhs, rhs, _) = &expr.kind { - if eq_expr_value(cx, lhs, rhs) { - let lhs = snippet(cx, lhs.span, ""); - let rhs = snippet(cx, rhs.span, ""); - span_lint( - cx, - SELF_ASSIGNMENT, - expr.span, - &format!("self-assignment of `{}` to `{}`", rhs, lhs), - ); - } - } - } -}