Skip to content

Commit d654c26

Browse files
eta_reduction: don't refer to ADT constructors as "function"s (#15436)
fixes #8817 changelog: [`eta_reduction`]: don't refer to ADT constructors as "function"s
2 parents 32a216e + ac9361e commit d654c26

File tree

4 files changed

+123
-37
lines changed

4 files changed

+123
-37
lines changed

clippy_lints/src/eta_reduction.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,13 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
231231
_ => (),
232232
}
233233
}
234+
let replace_with = match callee_ty_adjusted.kind() {
235+
ty::FnDef(def, _) => cx.tcx.def_descr(*def),
236+
_ => "function",
237+
};
234238
diag.span_suggestion(
235239
expr.span,
236-
"replace the closure with the function itself",
240+
format!("replace the closure with the {replace_with} itself"),
237241
snippet,
238242
Applicability::MachineApplicable,
239243
);

tests/ui/eta.fixed

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// we have some HELP annotations -- don't complain about them not being present everywhere
2+
//@require-annotations-for-level: ERROR
3+
14
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
25
#![allow(unused)]
36
#![allow(
@@ -561,3 +564,29 @@ fn issue_14789() {
561564
std::convert::identity,
562565
);
563566
}
567+
568+
fn issue8817() {
569+
fn f(_: u32) -> u32 {
570+
todo!()
571+
}
572+
let g = |_: u32| -> u32 { todo!() };
573+
struct S(u32);
574+
enum MyError {
575+
A(S),
576+
}
577+
578+
Some(5)
579+
.map(f)
580+
//~^ redundant_closure
581+
//~| HELP: replace the closure with the function itself
582+
.map(g)
583+
//~^ redundant_closure
584+
//~| HELP: replace the closure with the function itself
585+
.map(S)
586+
//~^ redundant_closure
587+
//~| HELP: replace the closure with the tuple struct itself
588+
.map(MyError::A)
589+
//~^ redundant_closure
590+
//~| HELP: replace the closure with the tuple variant itself
591+
.unwrap(); // just for nicer formatting
592+
}

tests/ui/eta.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// we have some HELP annotations -- don't complain about them not being present everywhere
2+
//@require-annotations-for-level: ERROR
3+
14
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
25
#![allow(unused)]
36
#![allow(
@@ -561,3 +564,29 @@ fn issue_14789() {
561564
std::convert::identity,
562565
);
563566
}
567+
568+
fn issue8817() {
569+
fn f(_: u32) -> u32 {
570+
todo!()
571+
}
572+
let g = |_: u32| -> u32 { todo!() };
573+
struct S(u32);
574+
enum MyError {
575+
A(S),
576+
}
577+
578+
Some(5)
579+
.map(|n| f(n))
580+
//~^ redundant_closure
581+
//~| HELP: replace the closure with the function itself
582+
.map(|n| g(n))
583+
//~^ redundant_closure
584+
//~| HELP: replace the closure with the function itself
585+
.map(|n| S(n))
586+
//~^ redundant_closure
587+
//~| HELP: replace the closure with the tuple struct itself
588+
.map(|n| MyError::A(n))
589+
//~^ redundant_closure
590+
//~| HELP: replace the closure with the tuple variant itself
591+
.unwrap(); // just for nicer formatting
592+
}

tests/ui/eta.stderr

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: redundant closure
2-
--> tests/ui/eta.rs:31:27
2+
--> tests/ui/eta.rs:34:27
33
|
44
LL | let a = Some(1u8).map(|a| foo(a));
55
| ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@@ -8,31 +8,31 @@ LL | let a = Some(1u8).map(|a| foo(a));
88
= help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
99

1010
error: redundant closure
11-
--> tests/ui/eta.rs:36:40
11+
--> tests/ui/eta.rs:39:40
1212
|
1313
LL | let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
1414
| ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
1515

1616
error: redundant closure
17-
--> tests/ui/eta.rs:39:35
17+
--> tests/ui/eta.rs:42:35
1818
|
1919
LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
2020
| ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
2121

2222
error: redundant closure
23-
--> tests/ui/eta.rs:42:26
23+
--> tests/ui/eta.rs:45:26
2424
|
2525
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
2626
| ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
2727

2828
error: redundant closure
29-
--> tests/ui/eta.rs:51:27
29+
--> tests/ui/eta.rs:54:27
3030
|
3131
LL | let e = Some(1u8).map(|a| generic(a));
3232
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
3333

3434
error: redundant closure
35-
--> tests/ui/eta.rs:104:51
35+
--> tests/ui/eta.rs:107:51
3636
|
3737
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
3838
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -41,178 +41,202 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
4141
= help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
4242

4343
error: redundant closure
44-
--> tests/ui/eta.rs:106:51
44+
--> tests/ui/eta.rs:109:51
4545
|
4646
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
4747
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
4848

4949
error: redundant closure
50-
--> tests/ui/eta.rs:109:42
50+
--> tests/ui/eta.rs:112:42
5151
|
5252
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
5353
| ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
5454

5555
error: redundant closure
56-
--> tests/ui/eta.rs:114:29
56+
--> tests/ui/eta.rs:117:29
5757
|
5858
LL | let e = Some("str").map(|s| s.to_string());
5959
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
6060

6161
error: redundant closure
62-
--> tests/ui/eta.rs:116:27
62+
--> tests/ui/eta.rs:119:27
6363
|
6464
LL | let e = Some('a').map(|s| s.to_uppercase());
6565
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
6666

6767
error: redundant closure
68-
--> tests/ui/eta.rs:119:65
68+
--> tests/ui/eta.rs:122:65
6969
|
7070
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
7171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
7272

7373
error: redundant closure
74-
--> tests/ui/eta.rs:136:23
74+
--> tests/ui/eta.rs:139:23
7575
|
7676
LL | let _ = x.map(|x| x.parse::<i16>());
7777
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::<i16>`
7878

7979
error: redundant closure
80-
--> tests/ui/eta.rs:189:22
80+
--> tests/ui/eta.rs:192:22
8181
|
8282
LL | requires_fn_once(|| x());
8383
| ^^^^^^ help: replace the closure with the function itself: `x`
8484

8585
error: redundant closure
86-
--> tests/ui/eta.rs:197:27
86+
--> tests/ui/eta.rs:200:27
8787
|
8888
LL | let a = Some(1u8).map(|a| foo_ptr(a));
8989
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
9090

9191
error: redundant closure
92-
--> tests/ui/eta.rs:203:27
92+
--> tests/ui/eta.rs:206:27
9393
|
9494
LL | let a = Some(1u8).map(|a| closure(a));
9595
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
9696

9797
error: redundant closure
98-
--> tests/ui/eta.rs:236:28
98+
--> tests/ui/eta.rs:239:28
9999
|
100100
LL | x.into_iter().for_each(|x| add_to_res(x));
101101
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
102102

103103
error: redundant closure
104-
--> tests/ui/eta.rs:238:28
104+
--> tests/ui/eta.rs:241:28
105105
|
106106
LL | y.into_iter().for_each(|x| add_to_res(x));
107107
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
108108

109109
error: redundant closure
110-
--> tests/ui/eta.rs:240:28
110+
--> tests/ui/eta.rs:243:28
111111
|
112112
LL | z.into_iter().for_each(|x| add_to_res(x));
113113
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
114114

115115
error: redundant closure
116-
--> tests/ui/eta.rs:248:21
116+
--> tests/ui/eta.rs:251:21
117117
|
118118
LL | Some(1).map(|n| closure(n));
119119
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
120120

121121
error: redundant closure
122-
--> tests/ui/eta.rs:253:21
122+
--> tests/ui/eta.rs:256:21
123123
|
124124
LL | Some(1).map(|n| in_loop(n));
125125
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
126126

127127
error: redundant closure
128-
--> tests/ui/eta.rs:347:18
128+
--> tests/ui/eta.rs:350:18
129129
|
130130
LL | takes_fn_mut(|| f());
131131
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
132132

133133
error: redundant closure
134-
--> tests/ui/eta.rs:351:19
134+
--> tests/ui/eta.rs:354:19
135135
|
136136
LL | takes_fn_once(|| f());
137137
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
138138

139139
error: redundant closure
140-
--> tests/ui/eta.rs:356:26
140+
--> tests/ui/eta.rs:359:26
141141
|
142142
LL | move || takes_fn_mut(|| f_used_once())
143143
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
144144

145145
error: redundant closure
146-
--> tests/ui/eta.rs:369:19
146+
--> tests/ui/eta.rs:372:19
147147
|
148148
LL | array_opt.map(|a| a.as_slice());
149149
| ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
150150

151151
error: redundant closure
152-
--> tests/ui/eta.rs:373:19
152+
--> tests/ui/eta.rs:376:19
153153
|
154154
LL | slice_opt.map(|s| s.len());
155155
| ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
156156

157157
error: redundant closure
158-
--> tests/ui/eta.rs:377:17
158+
--> tests/ui/eta.rs:380:17
159159
|
160160
LL | ptr_opt.map(|p| p.is_null());
161161
| ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
162162

163163
error: redundant closure
164-
--> tests/ui/eta.rs:382:17
164+
--> tests/ui/eta.rs:385:17
165165
|
166166
LL | dyn_opt.map(|d| d.method_on_dyn());
167167
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
168168

169169
error: redundant closure
170-
--> tests/ui/eta.rs:443:19
170+
--> tests/ui/eta.rs:446:19
171171
|
172172
LL | let _ = f(&0, |x, y| f2(x, y));
173173
| ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
174174

175175
error: redundant closure
176-
--> tests/ui/eta.rs:472:22
176+
--> tests/ui/eta.rs:475:22
177177
|
178178
LL | test.map(|t| t.method())
179179
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`
180180

181181
error: redundant closure
182-
--> tests/ui/eta.rs:477:22
182+
--> tests/ui/eta.rs:480:22
183183
|
184184
LL | test.map(|t| t.method())
185185
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method`
186186

187187
error: redundant closure
188-
--> tests/ui/eta.rs:491:18
188+
--> tests/ui/eta.rs:494:18
189189
|
190190
LL | test.map(|t| t.method())
191191
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method`
192192

193193
error: redundant closure
194-
--> tests/ui/eta.rs:499:30
194+
--> tests/ui/eta.rs:502:30
195195
|
196196
LL | test.map(|t| t.method())
197197
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`
198198

199199
error: redundant closure
200-
--> tests/ui/eta.rs:519:38
200+
--> tests/ui/eta.rs:522:38
201201
|
202202
LL | let x = Box::new(|| None.map(|x| f(x)));
203203
| ^^^^^^^^ help: replace the closure with the function itself: `&f`
204204

205205
error: redundant closure
206-
--> tests/ui/eta.rs:524:38
206+
--> tests/ui/eta.rs:527:38
207207
|
208208
LL | let x = Box::new(|| None.map(|x| f(x)));
209209
| ^^^^^^^^ help: replace the closure with the function itself: `f`
210210

211211
error: redundant closure
212-
--> tests/ui/eta.rs:542:35
212+
--> tests/ui/eta.rs:545:35
213213
|
214214
LL | let _field = bind.or_else(|| get_default()).unwrap();
215215
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
216216

217-
error: aborting due to 35 previous errors
217+
error: redundant closure
218+
--> tests/ui/eta.rs:588:14
219+
|
220+
LL | .map(|n| MyError::A(n))
221+
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the tuple variant itself: `MyError::A`
222+
223+
error: redundant closure
224+
--> tests/ui/eta.rs:585:14
225+
|
226+
LL | .map(|n| S(n))
227+
| ^^^^^^^^ help: replace the closure with the tuple struct itself: `S`
228+
229+
error: redundant closure
230+
--> tests/ui/eta.rs:582:14
231+
|
232+
LL | .map(|n| g(n))
233+
| ^^^^^^^^ help: replace the closure with the function itself: `g`
234+
235+
error: redundant closure
236+
--> tests/ui/eta.rs:579:14
237+
|
238+
LL | .map(|n| f(n))
239+
| ^^^^^^^^ help: replace the closure with the function itself: `f`
240+
241+
error: aborting due to 39 previous errors
218242

0 commit comments

Comments
 (0)