about summary refs log tree commit diff
diff options
context:
space:
mode:
authory21 <30553356+y21@users.noreply.github.com>2023-06-07 22:57:15 +0200
committery21 <30553356+y21@users.noreply.github.com>2023-06-07 22:57:15 +0200
commit2c7cf2cfa113e28e82854574eb1227d7c001d84c (patch)
treed77dab5967eae6fccdd356b69bdfc9cf50064179
parent7c34ec8947f00f316f66ce2ed7068a0395828833 (diff)
handle RangeInclusive function desugar
-rw-r--r--clippy_lints/src/eta_reduction.rs10
-rw-r--r--tests/ui/eta.fixed6
-rw-r--r--tests/ui/eta.rs6
-rw-r--r--tests/ui/eta.stderr50
4 files changed, 49 insertions, 23 deletions
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs
index c919b4de65d..fcbf0898890 100644
--- a/clippy_lints/src/eta_reduction.rs
+++ b/clippy_lints/src/eta_reduction.rs
@@ -123,7 +123,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
             then {
                 span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
                     if let Some(mut snippet) = snippet_opt(cx, callee.span) {
-                        if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
+                        if let Some(higher::Range {
+                            start: Some(_),
+                            end: Some(_),
+                            limits: rustc_ast::RangeLimits::Closed
+                        }) = higher::Range::hir(body.value) {
+                            // `|x,y| x..=y` becomes `|x, y| RangeInclusive::new(x, y)`
+                            snippet = "core::ops::RangeInclusive::new".to_owned();
+                        } else if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
                             && let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs()
                             && implements_trait(
                                    cx,
@@ -136,6 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
                                 // Mutable closure is used after current expr; we cannot consume it.
                                 snippet = format!("&mut {snippet}");
                         }
+
                         diag.span_suggestion(
                             expr.span,
                             "replace the closure with the function itself",
diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed
index b1baf462c0f..934deb66362 100644
--- a/tests/ui/eta.fixed
+++ b/tests/ui/eta.fixed
@@ -46,6 +46,12 @@ fn main() {
 
     // issue #7224
     let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);
+
+    // issue #10684
+    fn test<T>(x: impl Fn(usize, usize) -> T) -> T {
+        x(1, 2)
+    }
+    test(core::ops::RangeInclusive::new);
 }
 
 trait TestTrait {
diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs
index e113c3d6cd6..978aecd24b3 100644
--- a/tests/ui/eta.rs
+++ b/tests/ui/eta.rs
@@ -46,6 +46,12 @@ fn main() {
 
     // issue #7224
     let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);
+
+    // issue #10684
+    fn test<T>(x: impl Fn(usize, usize) -> T) -> T {
+        x(1, 2)
+    }
+    test(|start, end| start..=end);
 }
 
 trait TestTrait {
diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr
index a521fb86860..1f5db2d5129 100644
--- a/tests/ui/eta.stderr
+++ b/tests/ui/eta.stderr
@@ -31,7 +31,13 @@ LL |     let e = Some(1u8).map(|a| generic(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
 
 error: redundant closure
-  --> $DIR/eta.rs:87:51
+  --> $DIR/eta.rs:54:10
+   |
+LL |     test(|start, end| start..=end);
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `core::ops::RangeInclusive::new`
+
+error: redundant closure
+  --> $DIR/eta.rs:93:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -39,124 +45,124 @@ LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
 
 error: redundant closure
-  --> $DIR/eta.rs:88:51
+  --> $DIR/eta.rs:94:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
    |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
 
 error: redundant closure
-  --> $DIR/eta.rs:90:42
+  --> $DIR/eta.rs:96:42
    |
 LL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
    |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
 
 error: redundant closure
-  --> $DIR/eta.rs:94:29
+  --> $DIR/eta.rs:100:29
    |
 LL |     let e = Some("str").map(|s| s.to_string());
    |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
 
 error: redundant closure
-  --> $DIR/eta.rs:95:27
+  --> $DIR/eta.rs:101:27
    |
 LL |     let e = Some('a').map(|s| s.to_uppercase());
    |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:97:65
+  --> $DIR/eta.rs:103:65
    |
 LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:160:22
+  --> $DIR/eta.rs:166:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> $DIR/eta.rs:167:27
+  --> $DIR/eta.rs:173:27
    |
 LL |     let a = Some(1u8).map(|a| foo_ptr(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
 
 error: redundant closure
-  --> $DIR/eta.rs:172:27
+  --> $DIR/eta.rs:178:27
    |
 LL |     let a = Some(1u8).map(|a| closure(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:204:28
+  --> $DIR/eta.rs:210:28
    |
 LL |     x.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:205:28
+  --> $DIR/eta.rs:211:28
    |
 LL |     y.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:206:28
+  --> $DIR/eta.rs:212:28
    |
 LL |     z.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:213:21
+  --> $DIR/eta.rs:219:21
    |
 LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:217:21
+  --> $DIR/eta.rs:223:21
    |
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
 error: redundant closure
-  --> $DIR/eta.rs:310:18
+  --> $DIR/eta.rs:316:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:313:19
+  --> $DIR/eta.rs:319:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:317:26
+  --> $DIR/eta.rs:323:26
    |
 LL |     move || takes_fn_mut(|| f_used_once())
    |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
 
 error: redundant closure
-  --> $DIR/eta.rs:329:19
+  --> $DIR/eta.rs:335:19
    |
 LL |     array_opt.map(|a| a.as_slice());
    |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
 
 error: redundant closure
-  --> $DIR/eta.rs:332:19
+  --> $DIR/eta.rs:338:19
    |
 LL |     slice_opt.map(|s| s.len());
    |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
 
 error: redundant closure
-  --> $DIR/eta.rs:335:17
+  --> $DIR/eta.rs:341:17
    |
 LL |     ptr_opt.map(|p| p.is_null());
    |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
 
 error: redundant closure
-  --> $DIR/eta.rs:339:17
+  --> $DIR/eta.rs:345:17
    |
 LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
-error: aborting due to 26 previous errors
+error: aborting due to 27 previous errors