Skip to content

Commit d5c62fd

Browse files
committed
Auto merge of #8431 - dswij:8416, r=xFrednet
`redundant_closure` fix FP on coerced closure Closes #8416, Closes #7812 Closes #8091 ~~Seems like this is fixed in #817 and regressed.~~ Ignore coerced closure false positives, but this will lead to some false negatives on resolvable generics. IMO, this is still an overall improvement changelog: [`redundant_closure`] ignores coerced closure
2 parents 18a1831 + 33bf9e9 commit d5c62fd

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

clippy_lints/src/eta_reduction.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::higher::VecArgs;
33
use clippy_utils::source::snippet_opt;
44
use clippy_utils::ty::is_type_diagnostic_item;
55
use clippy_utils::usage::local_used_after_expr;
6-
use clippy_utils::{higher, path_to_local, path_to_local_id};
6+
use clippy_utils::{higher, is_adjusted, path_to_local, path_to_local_id};
77
use if_chain::if_chain;
88
use rustc_errors::Applicability;
99
use rustc_hir::def_id::DefId;
@@ -103,6 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
103103
let closure_ty = cx.typeck_results().expr_ty(expr);
104104

105105
if_chain!(
106+
if !is_adjusted(cx, &body.value);
106107
if let ExprKind::Call(callee, args) = body.value.kind;
107108
if let ExprKind::Path(_) = callee.kind;
108109
if check_inputs(cx, body.params, args);
@@ -144,6 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
144145
);
145146

146147
if_chain!(
148+
if !is_adjusted(cx, &body.value);
147149
if let ExprKind::MethodCall(path, args, _) = body.value.kind;
148150
if check_inputs(cx, body.params, args);
149151
let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();

tests/ui/eta.fixed

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
}
3838

3939
// See #815
40-
let e = Some(1u8).map(divergent);
40+
let e = Some(1u8).map(|a| divergent(a));
4141
let e = Some(1u8).map(generic);
4242
let e = Some(1u8).map(generic);
4343
// See #515
@@ -233,7 +233,7 @@ fn late_bound_lifetimes() {
233233
{
234234
}
235235
map_str(|s| take_asref_path(s));
236-
map_str_to_path(std::convert::AsRef::as_ref);
236+
map_str_to_path(|s| s.as_ref());
237237
}
238238

239239
mod type_param_bound {
@@ -279,3 +279,15 @@ mod bind_by_ref {
279279
Some(A).map(|ref a| B::from(a));
280280
}
281281
}
282+
283+
// #7812 False positive on coerced closure
284+
fn coerced_closure() {
285+
fn function_returning_unit<F: FnMut(i32)>(f: F) {}
286+
function_returning_unit(|x| std::process::exit(x));
287+
288+
fn arr() -> &'static [u8; 0] {
289+
&[]
290+
}
291+
fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}
292+
slice_fn(|| arr());
293+
}

tests/ui/eta.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,15 @@ mod bind_by_ref {
279279
Some(A).map(|ref a| B::from(a));
280280
}
281281
}
282+
283+
// #7812 False positive on coerced closure
284+
fn coerced_closure() {
285+
fn function_returning_unit<F: FnMut(i32)>(f: F) {}
286+
function_returning_unit(|x| std::process::exit(x));
287+
288+
fn arr() -> &'static [u8; 0] {
289+
&[]
290+
}
291+
fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}
292+
slice_fn(|| arr());
293+
}

tests/ui/eta.stderr

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ error: redundant closure
2424
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
2525
| ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
2626

27-
error: redundant closure
28-
--> $DIR/eta.rs:40:27
29-
|
30-
LL | let e = Some(1u8).map(|a| divergent(a));
31-
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `divergent`
32-
3327
error: redundant closure
3428
--> $DIR/eta.rs:41:27
3529
|
@@ -122,11 +116,5 @@ error: redundant closure
122116
LL | Some(1).map(|n| in_loop(n));
123117
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
124118

125-
error: redundant closure
126-
--> $DIR/eta.rs:236:21
127-
|
128-
LL | map_str_to_path(|s| s.as_ref());
129-
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::convert::AsRef::as_ref`
130-
131-
error: aborting due to 21 previous errors
119+
error: aborting due to 19 previous errors
132120

0 commit comments

Comments
 (0)