Skip to content
Permalink
Browse files

Auto merge of #4101 - mikerite:redundant_closures_for_method_calls, r…

…=Manishearth

Split redundant_closure lint

Move the method checking into a new lint called
`redundant_closures_for_method_calls` and put it in the pedantic group.

This aspect of the lint seems more controversial than the rest.

cc #3942

changelog: Move method checking from `redundant_closure` to a new `pedantic` lint called `redundant_closure_for_method_calls`.
  • Loading branch information...
bors committed May 16, 2019
2 parents f49d878 + 08d2a0d commit 11194e3d050f45ff002a775f451ff6222fcd5b2c
Showing with 56 additions and 21 deletions.
  1. +1 −0 CHANGELOG.md
  2. +1 −1 README.md
  3. +25 −2 clippy_lints/src/eta_reduction.rs
  4. +1 −0 clippy_lints/src/lib.rs
  5. +5 −1 tests/ui/eta.fixed
  6. +5 −1 tests/ui/eta.rs
  7. +16 −14 tests/ui/eta.stderr
  8. +1 −1 tests/ui/map_clone.fixed
  9. +1 −1 tests/ui/map_clone.rs
@@ -1035,6 +1035,7 @@ All notable changes to this project will be documented in this file.
[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call
[`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
@@ -7,7 +7,7 @@

A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.

[There are 301 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are 302 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)

We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:

@@ -32,7 +32,30 @@ declare_clippy_lint! {
"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
}

declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE]);
declare_clippy_lint! {
/// **What it does:** Checks for closures which only invoke a method on the closure
/// argument and can be replaced by referencing the method directly.
///
/// **Why is this bad?** It's unnecessary to create the closure.
///
/// **Known problems:** rust-lang/rust-clippy#3071, rust-lang/rust-clippy#4002,
/// rust-lang/rust-clippy#3942
///
///
/// **Example:**
/// ```rust,ignore
/// Some('a').map(|s| s.to_uppercase());
/// ```
/// may be rewritten as
/// ```rust,ignore
/// Some('a').map(char::to_uppercase);
/// ```
pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
pedantic,
"redundant closures for method calls"
}

declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE, REDUNDANT_CLOSURE_FOR_METHOD_CALLS]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaReduction {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
@@ -104,7 +127,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) {
if let Some(name) = get_ufcs_type_name(cx, method_def_id, &args[0]);

then {
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| {
span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure found", |db| {
db.span_suggestion(
expr.span,
"remove closure as shown",
@@ -614,6 +614,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
enum_glob_use::ENUM_GLOB_USE,
enum_variants::MODULE_NAME_REPETITIONS,
enum_variants::PUB_ENUM_VARIANT_NAMES,
eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
functions::TOO_MANY_LINES,
if_not_else::IF_NOT_ELSE,
infinite_iter::MAYBE_INFINITE_ITER,
@@ -9,7 +9,11 @@
clippy::option_map_unit_fn,
clippy::trivially_copy_pass_by_ref
)]
#![warn(clippy::redundant_closure, clippy::needless_borrow)]
#![warn(
clippy::redundant_closure,
clippy::redundant_closure_for_method_calls,
clippy::needless_borrow
)]

use std::path::PathBuf;

@@ -9,7 +9,11 @@
clippy::option_map_unit_fn,
clippy::trivially_copy_pass_by_ref
)]
#![warn(clippy::redundant_closure, clippy::needless_borrow)]
#![warn(
clippy::redundant_closure,
clippy::redundant_closure_for_method_calls,
clippy::needless_borrow
)]

use std::path::PathBuf;

@@ -1,87 +1,89 @@
error: redundant closure found
--> $DIR/eta.rs:17:27
--> $DIR/eta.rs:21:27
|
LL | let a = Some(1u8).map(|a| foo(a));
| ^^^^^^^^^^ help: remove closure as shown: `foo`
|
= note: `-D clippy::redundant-closure` implied by `-D warnings`

error: redundant closure found
--> $DIR/eta.rs:18:10
--> $DIR/eta.rs:22:10
|
LL | meta(|a| foo(a));
| ^^^^^^^^^^ help: remove closure as shown: `foo`

error: redundant closure found
--> $DIR/eta.rs:19:27
--> $DIR/eta.rs:23:27
|
LL | let c = Some(1u8).map(|a| {1+2; foo}(a));
| ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `{1+2; foo}`

error: this expression borrows a reference that is immediately dereferenced by the compiler
--> $DIR/eta.rs:21:21
--> $DIR/eta.rs:25:21
|
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
| ^^^ help: change this to: `&2`
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`

error: redundant closure found
--> $DIR/eta.rs:28:27
--> $DIR/eta.rs:32:27
|
LL | let e = Some(1u8).map(|a| generic(a));
| ^^^^^^^^^^^^^^ help: remove closure as shown: `generic`

error: redundant closure found
--> $DIR/eta.rs:71:51
--> $DIR/eta.rs:75:51
|
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
| ^^^^^^^^^^^ help: remove closure as shown: `TestStruct::foo`
|
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`

error: redundant closure found
--> $DIR/eta.rs:73:51
--> $DIR/eta.rs:77:51
|
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
| ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `TestTrait::trait_foo`

error: redundant closure found
--> $DIR/eta.rs:76:42
--> $DIR/eta.rs:80:42
|
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
| ^^^^^^^^^^^^^ help: remove closure as shown: `std::vec::Vec::clear`

error: redundant closure found
--> $DIR/eta.rs:81:29
--> $DIR/eta.rs:85:29
|
LL | let e = Some("str").map(|s| s.to_string());
| ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `std::string::ToString::to_string`

error: redundant closure found
--> $DIR/eta.rs:83:27
--> $DIR/eta.rs:87:27
|
LL | let e = Some('a').map(|s| s.to_uppercase());
| ^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_uppercase`

error: redundant closure found
--> $DIR/eta.rs:86:65
--> $DIR/eta.rs:90:65
|
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_ascii_uppercase`

error: redundant closure found
--> $DIR/eta.rs:104:50
--> $DIR/eta.rs:108:50
|
LL | let _: Vec<_> = arr.iter().map(|x| x.map_err(|e| some.take().unwrap()(e))).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `some.take().unwrap()`

error: redundant closure found
--> $DIR/eta.rs:169:27
--> $DIR/eta.rs:173:27
|
LL | let a = Some(1u8).map(|a| foo_ptr(a));
| ^^^^^^^^^^^^^^ help: remove closure as shown: `foo_ptr`

error: redundant closure found
--> $DIR/eta.rs:174:27
--> $DIR/eta.rs:178:27
|
LL | let a = Some(1u8).map(|a| closure(a));
| ^^^^^^^^^^^^^^ help: remove closure as shown: `closure`
@@ -3,7 +3,7 @@
#![allow(clippy::iter_cloned_collect)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::missing_docs_in_private_items)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::redundant_closure_for_method_calls)]

fn main() {
let _: Vec<i8> = vec![5_i8; 6].iter().copied().collect();
@@ -3,7 +3,7 @@
#![allow(clippy::iter_cloned_collect)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::missing_docs_in_private_items)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::redundant_closure_for_method_calls)]

fn main() {
let _: Vec<i8> = vec![5_i8; 6].iter().map(|x| *x).collect();

0 comments on commit 11194e3

Please sign in to comment.
You can’t perform that action at this time.