diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed new file mode 100644 index 000000000000..7e487fe21679 --- /dev/null +++ b/tests/ui/eta.fixed @@ -0,0 +1,135 @@ +// run-rustfix + +#![allow( + unused, + clippy::no_effect, + clippy::redundant_closure_call, + clippy::many_single_char_names, + clippy::needless_pass_by_value, + clippy::option_map_unit_fn, + clippy::trivially_copy_pass_by_ref +)] +#![warn(clippy::redundant_closure, clippy::needless_borrow)] + +use std::path::PathBuf; + +fn main() { + let a = Some(1u8).map(foo); + meta(foo); + let c = Some(1u8).map({1+2; foo}); + let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? + all(&[1, 2, 3], &2, |x, y| below(x, y)); //is adjusted + unsafe { + Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn + } + + // See #815 + let e = Some(1u8).map(|a| divergent(a)); + let e = Some(1u8).map(generic); + let e = Some(1u8).map(generic); + // See #515 + let a: Option>> = + Some(vec![1i32, 2]).map(|v| -> Box<::std::ops::Deref> { Box::new(v) }); +} + +trait TestTrait { + fn trait_foo(self) -> bool; + fn trait_foo_ref(&self) -> bool; +} + +struct TestStruct<'a> { + some_ref: &'a i32, +} + +impl<'a> TestStruct<'a> { + fn foo(self) -> bool { + false + } + unsafe fn foo_unsafe(self) -> bool { + true + } +} + +impl<'a> TestTrait for TestStruct<'a> { + fn trait_foo(self) -> bool { + false + } + fn trait_foo_ref(&self) -> bool { + false + } +} + +impl<'a> std::ops::Deref for TestStruct<'a> { + type Target = char; + fn deref(&self) -> &char { + &'a' + } +} + +fn test_redundant_closures_containing_method_calls() { + let i = 10; + let e = Some(TestStruct { some_ref: &i }).map(TestStruct::foo); + let e = Some(TestStruct { some_ref: &i }).map(TestStruct::foo); + let e = Some(TestStruct { some_ref: &i }).map(TestTrait::trait_foo); + let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo_ref()); + let e = Some(TestStruct { some_ref: &i }).map(TestTrait::trait_foo); + let e = Some(&mut vec![1, 2, 3]).map(std::vec::Vec::clear); + let e = Some(&mut vec![1, 2, 3]).map(std::vec::Vec::clear); + unsafe { + let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo_unsafe()); + } + let e = Some("str").map(std::string::ToString::to_string); + let e = Some("str").map(str::to_string); + let e = Some('a').map(char::to_uppercase); + let e = Some('a').map(char::to_uppercase); + let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect(); + let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(char::to_ascii_uppercase).collect(); + let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(char::to_ascii_uppercase).collect(); + let p = Some(PathBuf::new()); + let e = p.as_ref().and_then(|s| s.to_str()); + let c = Some(TestStruct { some_ref: &i }) + .as_ref() + .map(|c| c.to_ascii_uppercase()); + + fn test_different_borrow_levels(t: &[&T]) + where + T: TestTrait, + { + t.iter().filter(|x| x.trait_foo_ref()); + t.iter().map(|x| x.trait_foo_ref()); + } +} + +fn meta(f: F) +where + F: Fn(u8), +{ + f(1u8) +} + +fn foo(_: u8) {} + +fn foo2(_: u8) -> u8 { + 1u8 +} + +fn all(x: &[X], y: &X, f: F) -> bool +where + F: Fn(&X, &X) -> bool, +{ + x.iter().all(|e| f(e, y)) +} + +fn below(x: &u8, y: &u8) -> bool { + x < y +} + +unsafe fn unsafe_fn(_: u8) {} + +fn divergent(_: u8) -> ! { + unimplemented!() +} + +fn generic(_: T) -> u8 { + 0 +} diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index f777939c67d2..a0d83c438251 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -1,3 +1,5 @@ +// run-rustfix + #![allow( unused, clippy::no_effect, diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 5f56cd7912a7..77423694f815 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -1,5 +1,5 @@ error: redundant closure found - --> $DIR/eta.rs:15:27 + --> $DIR/eta.rs:17:27 | LL | let a = Some(1u8).map(|a| foo(a)); | ^^^^^^^^^^ help: remove closure as shown: `foo` @@ -7,19 +7,19 @@ LL | let a = Some(1u8).map(|a| foo(a)); = note: `-D clippy::redundant-closure` implied by `-D warnings` error: redundant closure found - --> $DIR/eta.rs:16:10 + --> $DIR/eta.rs:18:10 | LL | meta(|a| foo(a)); | ^^^^^^^^^^ help: remove closure as shown: `foo` error: redundant closure found - --> $DIR/eta.rs:17:27 + --> $DIR/eta.rs:19: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:19:21 + --> $DIR/eta.rs:21:21 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^ help: change this to: `&2` @@ -27,43 +27,43 @@ LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted = note: `-D clippy::needless-borrow` implied by `-D warnings` error: redundant closure found - --> $DIR/eta.rs:26:27 + --> $DIR/eta.rs:28:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: remove closure as shown: `generic` error: redundant closure found - --> $DIR/eta.rs:69:51 + --> $DIR/eta.rs:71:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: remove closure as shown: `TestStruct::foo` error: redundant closure found - --> $DIR/eta.rs:71:51 + --> $DIR/eta.rs:73: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:74:42 + --> $DIR/eta.rs:76: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:79:29 + --> $DIR/eta.rs:81: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:81:27 + --> $DIR/eta.rs:83: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:84:65 + --> $DIR/eta.rs:86:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_ascii_uppercase`