From 008ba2b8bb711b8ee725a808f3d9ee65c2a1dce3 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Sat, 3 Jun 2023 19:58:27 -0700 Subject: [PATCH] new lint: redundant_local fix dogfood lints in `redundant_local` keep `redundant_local` from running in proc macros rewrite `redundant_local` as late pass make redundant_local's `find_binding` more readable pluralize `redundant_locals` name add test for `redundant_locals` in macros test `redundant_locals` in proc macros use more destructuring in `redundant_locals` fix: format redundant_locals.rs ignore needless_pass_by_mut_ref in redundant_locals test --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/redundant_locals.rs | 103 ++++++++++++++++++++ tests/ui/option_if_let_else.fixed | 3 +- tests/ui/option_if_let_else.rs | 3 +- tests/ui/option_if_let_else.stderr | 46 ++++----- tests/ui/redundant_locals.rs | 111 ++++++++++++++++++++++ tests/ui/redundant_locals.stderr | 136 +++++++++++++++++++++++++++ tests/ui/shadow.rs | 2 +- tests/ui/swap.fixed | 3 +- tests/ui/swap.rs | 3 +- tests/ui/swap.stderr | 34 +++---- 13 files changed, 403 insertions(+), 45 deletions(-) create mode 100644 clippy_lints/src/redundant_locals.rs create mode 100644 tests/ui/redundant_locals.rs create mode 100644 tests/ui/redundant_locals.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8797121..2b53f1df7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5190,6 +5190,7 @@ Released 2018-09-13 [`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else [`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names [`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names +[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals [`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern [`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching [`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 830714ce7..e92d9fa7f 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -561,6 +561,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO, crate::redundant_else::REDUNDANT_ELSE_INFO, crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO, + crate::redundant_locals::REDUNDANT_LOCALS_INFO, crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO, crate::redundant_slicing::DEREF_BY_SLICING_INFO, crate::redundant_slicing::REDUNDANT_SLICING_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 0fa5c2f18..ca2f5191c 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -275,6 +275,7 @@ mod redundant_clone; mod redundant_closure_call; mod redundant_else; mod redundant_field_names; +mod redundant_locals; mod redundant_pub_crate; mod redundant_slicing; mod redundant_static_lifetimes; @@ -1091,6 +1092,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: absolute_paths_allowed_crates: absolute_paths_allowed_crates.clone(), }) }); + store.register_late_pass(|_| Box::new(redundant_locals::RedundantLocals)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs new file mode 100644 index 000000000..140ae837a --- /dev/null +++ b/clippy_lints/src/redundant_locals.rs @@ -0,0 +1,103 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::is_from_proc_macro; +use clippy_utils::ty::needs_ordered_drop; +use rustc_hir::def::Res; +use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::Ident; + +declare_clippy_lint! { + /// ### What it does + /// Checks for redundant redefinitions of local bindings. + /// + /// ### Why is this bad? + /// Redundant redefinitions of local bindings do not change behavior and are likely to be unintended. + /// + /// Note that although these bindings do not affect your code's meaning, they _may_ affect `rustc`'s stack allocation. + /// + /// ### Example + /// ```rust + /// let a = 0; + /// let a = a; + /// + /// fn foo(b: i32) { + /// let b = b; + /// } + /// ``` + /// Use instead: + /// ```rust + /// let a = 0; + /// // no redefinition with the same name + /// + /// fn foo(b: i32) { + /// // no redefinition with the same name + /// } + /// ``` + #[clippy::version = "1.72.0"] + pub REDUNDANT_LOCALS, + correctness, + "redundant redefinition of a local binding" +} +declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]); + +impl<'tcx> LateLintPass<'tcx> for RedundantLocals { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + if_chain! { + // the pattern is a single by-value binding + if let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind; + // the binding is not type-ascribed + if local.ty.is_none(); + // the expression is a resolved path + if let Some(expr) = local.init; + if let ExprKind::Path(qpath @ QPath::Resolved(None, path)) = expr.kind; + // the path is a single segment equal to the local's name + if let [last_segment] = path.segments; + if last_segment.ident == ident; + // resolve the path to its defining binding pattern + if let Res::Local(binding_id) = cx.qpath_res(&qpath, expr.hir_id); + if let Node::Pat(binding_pat) = cx.tcx.hir().get(binding_id); + // the previous binding has the same mutability + if find_binding(binding_pat, ident).unwrap().1 == mutability; + // the local does not affect the code's drop behavior + if !affects_drop_behavior(cx, binding_id, local.hir_id, expr); + // the local is user-controlled + if !in_external_macro(cx.sess(), local.span); + if !is_from_proc_macro(cx, expr); + then { + span_lint_and_help( + cx, + REDUNDANT_LOCALS, + vec![binding_pat.span, local.span], + "redundant redefinition of a binding", + None, + &format!("remove the redefinition of `{ident}`"), + ); + } + } + } +} + +/// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced. +fn find_binding(pat: &Pat<'_>, name: Ident) -> Option { + let mut ret = None; + + pat.each_binding_or_first(&mut |annotation, _, _, ident| { + if ident == name { + ret = Some(annotation); + } + }); + + ret +} + +/// Check if a rebinding of a local affects the code's drop behavior. +fn affects_drop_behavior<'tcx>(cx: &LateContext<'tcx>, bind: HirId, rebind: HirId, rebind_expr: &Expr<'tcx>) -> bool { + let hir = cx.tcx.hir(); + + // the rebinding is in a different scope than the original binding + // and the type of the binding cares about drop order + hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind) + && needs_ordered_drop(cx, cx.typeck_results().expr_ty(rebind_expr)) +} diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 8e59e4375..6fee3cce6 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -5,7 +5,8 @@ clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, - clippy::let_unit_value + clippy::let_unit_value, + clippy::redundant_locals )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index e72edf2a8..4b3cf948a 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -5,7 +5,8 @@ clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, - clippy::let_unit_value + clippy::let_unit_value, + clippy::redundant_locals )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index aa2da2174..350f0f07e 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:12:5 + --> $DIR/option_if_let_else.rs:13:5 | LL | / if let Some(x) = string { LL | | (true, x) @@ -11,19 +11,19 @@ LL | | } = note: `-D clippy::option-if-let-else` implied by `-D warnings` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:30:13 + --> $DIR/option_if_let_else.rs:31:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:31:13 + --> $DIR/option_if_let_else.rs:32:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:32:13 + --> $DIR/option_if_let_else.rs:33:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -43,13 +43,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:38:13 + --> $DIR/option_if_let_else.rs:39:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:39:13 + --> $DIR/option_if_let_else.rs:40:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -69,7 +69,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:45:13 + --> $DIR/option_if_let_else.rs:46:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -89,7 +89,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:54:5 + --> $DIR/option_if_let_else.rs:55:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -108,7 +108,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:67:13 + --> $DIR/option_if_let_else.rs:68:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -120,7 +120,7 @@ LL | | }; | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:76:13 + --> $DIR/option_if_let_else.rs:77:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -143,7 +143,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:109:13 + --> $DIR/option_if_let_else.rs:110:13 | LL | / if let Some(idx) = s.find('.') { LL | | vec![s[..idx].to_string(), s[idx..].to_string()] @@ -153,7 +153,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:120:5 + --> $DIR/option_if_let_else.rs:121:5 | LL | / if let Ok(binding) = variable { LL | | println!("Ok {binding}"); @@ -172,13 +172,13 @@ LL + }) | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:142:13 + --> $DIR/option_if_let_else.rs:143:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:152:13 + --> $DIR/option_if_let_else.rs:153:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -200,13 +200,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:180:13 + --> $DIR/option_if_let_else.rs:181:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:184:13 + --> $DIR/option_if_let_else.rs:185:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -226,7 +226,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:223:13 + --> $DIR/option_if_let_else.rs:224:13 | LL | let _ = match s { | _____________^ @@ -236,7 +236,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:227:13 + --> $DIR/option_if_let_else.rs:228:13 | LL | let _ = match Some(10) { | _____________^ @@ -246,7 +246,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:233:13 + --> $DIR/option_if_let_else.rs:234:13 | LL | let _ = match res { | _____________^ @@ -256,7 +256,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:237:13 + --> $DIR/option_if_let_else.rs:238:13 | LL | let _ = match res { | _____________^ @@ -266,13 +266,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:241:13 + --> $DIR/option_if_let_else.rs:242:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:258:9 + --> $DIR/option_if_let_else.rs:259:9 | LL | / match initial { LL | | Some(value) => do_something(value), @@ -281,7 +281,7 @@ LL | | } | |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:265:9 + --> $DIR/option_if_let_else.rs:266:9 | LL | / match initial { LL | | Some(value) => do_something2(value), diff --git a/tests/ui/redundant_locals.rs b/tests/ui/redundant_locals.rs new file mode 100644 index 000000000..e74c78a50 --- /dev/null +++ b/tests/ui/redundant_locals.rs @@ -0,0 +1,111 @@ +//@aux-build:proc_macros.rs:proc-macro +#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)] +#![warn(clippy::redundant_locals)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; + +fn main() {} + +fn immutable() { + let x = 1; + let x = x; +} + +fn mutable() { + let mut x = 1; + let mut x = x; +} + +fn upgraded_mutability() { + let x = 1; + let mut x = x; +} + +fn downgraded_mutability() { + let mut x = 1; + let x = x; +} + +fn coercion(par: &mut i32) { + let par: &i32 = par; + + let x: &mut i32 = &mut 1; + let x: &i32 = x; +} + +fn parameter(x: i32) { + let x = x; +} + +fn many() { + let x = 1; + let x = x; + let x = x; + let x = x; + let x = x; +} + +fn interleaved() { + let a = 1; + let b = 2; + let a = a; + let b = b; +} + +fn block() { + { + let x = 1; + let x = x; + } +} + +fn closure() { + || { + let x = 1; + let x = x; + }; + |x: i32| { + let x = x; + }; +} + +fn consequential_drop_order() { + use std::sync::Mutex; + + let mutex = Mutex::new(1); + let guard = mutex.lock().unwrap(); + + { + let guard = guard; + } +} + +fn inconsequential_drop_order() { + let x = 1; + + { + let x = x; + } +} + +fn macros() { + macro_rules! rebind { + ($x:ident) => { + let $x = 1; + let $x = $x; + }; + } + + rebind!(x); + + external! { + let x = 1; + let x = x; + } + with_span! { + span + let x = 1; + let x = x; + } +} diff --git a/tests/ui/redundant_locals.stderr b/tests/ui/redundant_locals.stderr new file mode 100644 index 000000000..df07dd2f4 --- /dev/null +++ b/tests/ui/redundant_locals.stderr @@ -0,0 +1,136 @@ +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:11:9 + | +LL | let x = 1; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + = note: `-D clippy::redundant-locals` implied by `-D warnings` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:16:9 + | +LL | let mut x = 1; + | ^^^^^ +LL | let mut x = x; + | ^^^^^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:37:14 + | +LL | fn parameter(x: i32) { + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:42:9 + | +LL | let x = 1; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:43:9 + | +LL | let x = x; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:44:9 + | +LL | let x = x; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:45:9 + | +LL | let x = x; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:50:9 + | +LL | let a = 1; + | ^ +LL | let b = 2; +LL | let a = a; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `a` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:51:9 + | +LL | let b = 2; + | ^ +LL | let a = a; +LL | let b = b; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `b` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:58:13 + | +LL | let x = 1; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:65:13 + | +LL | let x = 1; + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:68:6 + | +LL | |x: i32| { + | ^ +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: redundant redefinition of a binding + --> $DIR/redundant_locals.rs:85:9 + | +LL | let x = 1; + | ^ +... +LL | let x = x; + | ^^^^^^^^^^ + | + = help: remove the redefinition of `x` + +error: aborting due to 13 previous errors + diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index 9be8c5e59..4d22b7d2a 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -1,7 +1,7 @@ //@aux-build:proc_macro_derive.rs:proc-macro #![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)] -#![allow(clippy::let_unit_value, clippy::needless_if)] +#![allow(clippy::let_unit_value, clippy::needless_if, clippy::redundant_locals)] extern crate proc_macro_derive; diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index 22f904e3f..7b74a83b6 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -11,7 +11,8 @@ unused_assignments, unused_variables, clippy::let_and_return, - clippy::useless_vec + clippy::useless_vec, + clippy::redundant_locals )] struct Foo(u32); diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index ada64f89e..93855cd7b 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -11,7 +11,8 @@ unused_assignments, unused_variables, clippy::let_and_return, - clippy::useless_vec + clippy::useless_vec, + clippy::redundant_locals )] struct Foo(u32); diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index a3b9c2b74..1097b29bb 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -1,5 +1,5 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:28:5 + --> $DIR/swap.rs:29:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; @@ -10,7 +10,7 @@ LL | | bar.b = temp; = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:40:5 + --> $DIR/swap.rs:41:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -18,7 +18,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:49:5 + --> $DIR/swap.rs:50:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -26,7 +26,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:68:5 + --> $DIR/swap.rs:69:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -34,7 +34,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:79:5 + --> $DIR/swap.rs:80:5 | LL | / a ^= b; LL | | b ^= a; @@ -42,7 +42,7 @@ LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:87:5 + --> $DIR/swap.rs:88:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; @@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:95:5 + --> $DIR/swap.rs:96:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; @@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> $DIR/swap.rs:124:5 + --> $DIR/swap.rs:125:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; @@ -68,7 +68,7 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:138:7 + --> $DIR/swap.rs:139:7 | LL | ; let t = a; | _______^ @@ -79,7 +79,7 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> $DIR/swap.rs:147:7 + --> $DIR/swap.rs:148:7 | LL | ; let t = c.0; | _______^ @@ -90,7 +90,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `b` and `a` manually - --> $DIR/swap.rs:173:5 + --> $DIR/swap.rs:174:5 | LL | / let t = b; LL | | b = a; @@ -100,7 +100,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:135:5 + --> $DIR/swap.rs:136:5 | LL | / a = b; LL | | b = a; @@ -110,7 +110,7 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` - --> $DIR/swap.rs:144:5 + --> $DIR/swap.rs:145:5 | LL | / c.0 = a; LL | | a = c.0; @@ -119,7 +119,7 @@ LL | | a = c.0; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:151:5 + --> $DIR/swap.rs:152:5 | LL | / let a = b; LL | | let b = a; @@ -128,7 +128,7 @@ LL | | let b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `d` and `c` - --> $DIR/swap.rs:156:5 + --> $DIR/swap.rs:157:5 | LL | / d = c; LL | | c = d; @@ -137,7 +137,7 @@ LL | | c = d; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:160:5 + --> $DIR/swap.rs:161:5 | LL | / let a = b; LL | | b = a; @@ -146,7 +146,7 @@ LL | | b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> $DIR/swap.rs:208:5 + --> $DIR/swap.rs:209:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y;