Skip to content

Commit ba1702a

Browse files
committed
Auto merge of #4190 - projedi:fix-eta, r=flip1995
Fixing eta with respect to lazy evaluation. This fixes #4187 changelog: `redundant_closure`: stop linting on expressions returning a function, which is then directly used by the closure
2 parents c0dbd34 + 41a4ce5 commit ba1702a

File tree

4 files changed

+19
-15
lines changed

4 files changed

+19
-15
lines changed

clippy_lints/src/eta_reduction.rs

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) {
8282
if_chain!(
8383
if let ExprKind::Call(ref caller, ref args) = ex.node;
8484

85+
if let ExprKind::Path(_) = caller.node;
86+
8587
// Not the same number of arguments, there is no way the closure is the same as the function return;
8688
if args.len() == decl.inputs.len();
8789

tests/ui/eta.fixed

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::path::PathBuf;
2020
fn main() {
2121
let a = Some(1u8).map(foo);
2222
meta(foo);
23-
let c = Some(1u8).map({1+2; foo});
23+
let c = Some(1u8).map(|a| {1+2; foo}(a));
2424
let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
2525
all(&[1, 2, 3], &2, |x, y| below(x, y)); //is adjusted
2626
unsafe {
@@ -105,7 +105,7 @@ fn test_redundant_closures_containing_method_calls() {
105105

106106
let mut some = Some(|x| x * x);
107107
let arr = [Ok(1), Err(2)];
108-
let _: Vec<_> = arr.iter().map(|x| x.map_err(some.take().unwrap())).collect();
108+
let _: Vec<_> = arr.iter().map(|x| x.map_err(|e| some.take().unwrap()(e))).collect();
109109
}
110110

111111
struct Thunk<T>(Box<dyn FnMut() -> T>);
@@ -177,3 +177,10 @@ fn test_redundant_closure_with_another_closure() {
177177
let closure = |a| println!("{}", a);
178178
let a = Some(1u8).map(closure);
179179
}
180+
181+
fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {
182+
// Currently f is called when result of make_lazy is called.
183+
// If the closure is removed, f will be called when make_lazy itself is
184+
// called. This changes semantics, so the closure must stay.
185+
Box::new(move |x| f()(x))
186+
}

tests/ui/eta.rs

+7
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,10 @@ fn test_redundant_closure_with_another_closure() {
177177
let closure = |a| println!("{}", a);
178178
let a = Some(1u8).map(|a| closure(a));
179179
}
180+
181+
fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {
182+
// Currently f is called when result of make_lazy is called.
183+
// If the closure is removed, f will be called when make_lazy itself is
184+
// called. This changes semantics, so the closure must stay.
185+
Box::new(move |x| f()(x))
186+
}

tests/ui/eta.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ error: redundant closure found
1212
LL | meta(|a| foo(a));
1313
| ^^^^^^^^^^ help: remove closure as shown: `foo`
1414

15-
error: redundant closure found
16-
--> $DIR/eta.rs:23:27
17-
|
18-
LL | let c = Some(1u8).map(|a| {1+2; foo}(a));
19-
| ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `{1+2; foo}`
20-
2115
error: this expression borrows a reference that is immediately dereferenced by the compiler
2216
--> $DIR/eta.rs:25:21
2317
|
@@ -70,12 +64,6 @@ error: redundant closure found
7064
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
7165
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_ascii_uppercase`
7266

73-
error: redundant closure found
74-
--> $DIR/eta.rs:108:50
75-
|
76-
LL | let _: Vec<_> = arr.iter().map(|x| x.map_err(|e| some.take().unwrap()(e))).collect();
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `some.take().unwrap()`
78-
7967
error: redundant closure found
8068
--> $DIR/eta.rs:173:27
8169
|
@@ -88,5 +76,5 @@ error: redundant closure found
8876
LL | let a = Some(1u8).map(|a| closure(a));
8977
| ^^^^^^^^^^^^^^ help: remove closure as shown: `closure`
9078

91-
error: aborting due to 14 previous errors
79+
error: aborting due to 12 previous errors
9280

0 commit comments

Comments
 (0)