about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-19 12:04:07 +0000
committerbors <bors@rust-lang.org>2023-10-19 12:04:07 +0000
commitcd477d4b0c49c6ad1524244d732bd74643881878 (patch)
tree4a45e179caebee7d7f51f6ecebf9777189b5a7d6
parent9574d28cb63c08f825865637a4cbf08597ccf5c9 (diff)
parent3e6db95e308593fac0b9f132454db44295a94b08 (diff)
downloadrust-cd477d4b0c49c6ad1524244d732bd74643881878.tar.gz
rust-cd477d4b0c49c6ad1524244d732bd74643881878.zip
Auto merge of #11621 - GuillaumeGomez:needless_pass_by_ref_mut-closure-non-async-fn, r=blyxyas
Needless pass by ref mut closure non async fn

Fixes https://github.com/rust-lang/rust-clippy/issues/11620.
Fixes https://github.com/rust-lang/rust-clippy/issues/11561.

changelog: [`needless_pass_by_ref_mut`]: Correctly handle arguments moved into closure in non-async functions.

r? `@Centri3`
-rw-r--r--clippy_lints/src/needless_pass_by_ref_mut.rs27
-rw-r--r--tests/ui/needless_pass_by_ref_mut.rs14
2 files changed, 28 insertions, 13 deletions
diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs
index e7424ba7c6d..1d5874f6fea 100644
--- a/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -197,20 +197,21 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
             };
             let infcx = cx.tcx.infer_ctxt().build();
             euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
-            if is_async {
-                let mut checked_closures = FxHashSet::default();
-
-                // We retrieve all the closures declared in the async function because they will
-                // not be found by `euv::Delegate`.
-                let mut closures: FxHashSet<LocalDefId> = FxHashSet::default();
-                for_each_expr_with_closures(cx, body, |expr| {
-                    if let ExprKind::Closure(closure) = expr.kind {
-                        closures.insert(closure.def_id);
-                    }
-                    ControlFlow::<()>::Continue(())
-                });
-                check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
 
+            let mut checked_closures = FxHashSet::default();
+
+            // We retrieve all the closures declared in the function because they will not be found
+            // by `euv::Delegate`.
+            let mut closures: FxHashSet<LocalDefId> = FxHashSet::default();
+            for_each_expr_with_closures(cx, body, |expr| {
+                if let ExprKind::Closure(closure) = expr.kind {
+                    closures.insert(closure.def_id);
+                }
+                ControlFlow::<()>::Continue(())
+            });
+            check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
+
+            if is_async {
                 while !ctx.async_closures.is_empty() {
                     let async_closures = ctx.async_closures.clone();
                     ctx.async_closures.clear();
diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs
index 7f642e53dfb..ea5e74c4c00 100644
--- a/tests/ui/needless_pass_by_ref_mut.rs
+++ b/tests/ui/needless_pass_by_ref_mut.rs
@@ -288,6 +288,20 @@ fn get_mut_unchecked2<T>(ptr: &mut NonNull<Data<T>>) -> &mut T {
     unsafe { &mut (*ptr.as_ptr()).value }
 }
 
+fn set_true(b: &mut bool) {
+    *b = true;
+}
+
+// Should not warn.
+fn true_setter(b: &mut bool) -> impl FnOnce() + '_ {
+    move || set_true(b)
+}
+
+// Should not warn.
+fn filter_copy<T: Copy>(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T) -> bool + '_ {
+    move |&item| predicate(item)
+}
+
 fn main() {
     let mut u = 0;
     let mut v = vec![0];