Skip to content

Commit 2c7cf2c

Browse files
committed
handle RangeInclusive function desugar
1 parent 7c34ec8 commit 2c7cf2c

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

clippy_lints/src/eta_reduction.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
123123
then {
124124
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
125125
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
126-
if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
126+
if let Some(higher::Range {
127+
start: Some(_),
128+
end: Some(_),
129+
limits: rustc_ast::RangeLimits::Closed
130+
}) = higher::Range::hir(body.value) {
131+
// `|x,y| x..=y` becomes `|x, y| RangeInclusive::new(x, y)`
132+
snippet = "core::ops::RangeInclusive::new".to_owned();
133+
} else if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
127134
&& let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs()
128135
&& implements_trait(
129136
cx,
@@ -136,6 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
136143
// Mutable closure is used after current expr; we cannot consume it.
137144
snippet = format!("&mut {snippet}");
138145
}
146+
139147
diag.span_suggestion(
140148
expr.span,
141149
"replace the closure with the function itself",

tests/ui/eta.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ fn main() {
4646

4747
// issue #7224
4848
let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);
49+
50+
// issue #10684
51+
fn test<T>(x: impl Fn(usize, usize) -> T) -> T {
52+
x(1, 2)
53+
}
54+
test(core::ops::RangeInclusive::new);
4955
}
5056

5157
trait TestTrait {

tests/ui/eta.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ fn main() {
4646

4747
// issue #7224
4848
let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);
49+
50+
// issue #10684
51+
fn test<T>(x: impl Fn(usize, usize) -> T) -> T {
52+
x(1, 2)
53+
}
54+
test(|start, end| start..=end);
4955
}
5056

5157
trait TestTrait {

tests/ui/eta.stderr

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,132 +31,138 @@ LL | let e = Some(1u8).map(|a| generic(a));
3131
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
3232

3333
error: redundant closure
34-
--> $DIR/eta.rs:87:51
34+
--> $DIR/eta.rs:54:10
35+
|
36+
LL | test(|start, end| start..=end);
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `core::ops::RangeInclusive::new`
38+
39+
error: redundant closure
40+
--> $DIR/eta.rs:93:51
3541
|
3642
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
3743
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
3844
|
3945
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
4046

4147
error: redundant closure
42-
--> $DIR/eta.rs:88:51
48+
--> $DIR/eta.rs:94:51
4349
|
4450
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
4551
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
4652

4753
error: redundant closure
48-
--> $DIR/eta.rs:90:42
54+
--> $DIR/eta.rs:96:42
4955
|
5056
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
5157
| ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
5258

5359
error: redundant closure
54-
--> $DIR/eta.rs:94:29
60+
--> $DIR/eta.rs:100:29
5561
|
5662
LL | let e = Some("str").map(|s| s.to_string());
5763
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
5864

5965
error: redundant closure
60-
--> $DIR/eta.rs:95:27
66+
--> $DIR/eta.rs:101:27
6167
|
6268
LL | let e = Some('a').map(|s| s.to_uppercase());
6369
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
6470

6571
error: redundant closure
66-
--> $DIR/eta.rs:97:65
72+
--> $DIR/eta.rs:103:65
6773
|
6874
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
6975
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
7076

7177
error: redundant closure
72-
--> $DIR/eta.rs:160:22
78+
--> $DIR/eta.rs:166:22
7379
|
7480
LL | requires_fn_once(|| x());
7581
| ^^^^^^ help: replace the closure with the function itself: `x`
7682

7783
error: redundant closure
78-
--> $DIR/eta.rs:167:27
84+
--> $DIR/eta.rs:173:27
7985
|
8086
LL | let a = Some(1u8).map(|a| foo_ptr(a));
8187
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
8288

8389
error: redundant closure
84-
--> $DIR/eta.rs:172:27
90+
--> $DIR/eta.rs:178:27
8591
|
8692
LL | let a = Some(1u8).map(|a| closure(a));
8793
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
8894

8995
error: redundant closure
90-
--> $DIR/eta.rs:204:28
96+
--> $DIR/eta.rs:210:28
9197
|
9298
LL | x.into_iter().for_each(|x| add_to_res(x));
9399
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
94100

95101
error: redundant closure
96-
--> $DIR/eta.rs:205:28
102+
--> $DIR/eta.rs:211:28
97103
|
98104
LL | y.into_iter().for_each(|x| add_to_res(x));
99105
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
100106

101107
error: redundant closure
102-
--> $DIR/eta.rs:206:28
108+
--> $DIR/eta.rs:212:28
103109
|
104110
LL | z.into_iter().for_each(|x| add_to_res(x));
105111
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
106112

107113
error: redundant closure
108-
--> $DIR/eta.rs:213:21
114+
--> $DIR/eta.rs:219:21
109115
|
110116
LL | Some(1).map(|n| closure(n));
111117
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
112118

113119
error: redundant closure
114-
--> $DIR/eta.rs:217:21
120+
--> $DIR/eta.rs:223:21
115121
|
116122
LL | Some(1).map(|n| in_loop(n));
117123
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
118124

119125
error: redundant closure
120-
--> $DIR/eta.rs:310:18
126+
--> $DIR/eta.rs:316:18
121127
|
122128
LL | takes_fn_mut(|| f());
123129
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
124130

125131
error: redundant closure
126-
--> $DIR/eta.rs:313:19
132+
--> $DIR/eta.rs:319:19
127133
|
128134
LL | takes_fn_once(|| f());
129135
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
130136

131137
error: redundant closure
132-
--> $DIR/eta.rs:317:26
138+
--> $DIR/eta.rs:323:26
133139
|
134140
LL | move || takes_fn_mut(|| f_used_once())
135141
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
136142

137143
error: redundant closure
138-
--> $DIR/eta.rs:329:19
144+
--> $DIR/eta.rs:335:19
139145
|
140146
LL | array_opt.map(|a| a.as_slice());
141147
| ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
142148

143149
error: redundant closure
144-
--> $DIR/eta.rs:332:19
150+
--> $DIR/eta.rs:338:19
145151
|
146152
LL | slice_opt.map(|s| s.len());
147153
| ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
148154

149155
error: redundant closure
150-
--> $DIR/eta.rs:335:17
156+
--> $DIR/eta.rs:341:17
151157
|
152158
LL | ptr_opt.map(|p| p.is_null());
153159
| ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
154160

155161
error: redundant closure
156-
--> $DIR/eta.rs:339:17
162+
--> $DIR/eta.rs:345:17
157163
|
158164
LL | dyn_opt.map(|d| d.method_on_dyn());
159165
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
160166

161-
error: aborting due to 26 previous errors
167+
error: aborting due to 27 previous errors
162168

0 commit comments

Comments
 (0)