6 clippy
::redundant_closure_call
,
7 clippy
::many_single_char_names
,
8 clippy
::needless_pass_by_value
,
9 clippy
::option_map_unit_fn
12 clippy
::redundant_closure
,
13 clippy
::redundant_closure_for_method_calls
,
14 clippy
::needless_borrow
17 use std
::path
::PathBuf
;
25 macro_rules
! closure_mac
{
32 let a
= Some(1u8).map(|a
| foo(a
));
34 let c
= Some(1u8).map(|a
| {1+2; foo}
(a
));
35 true.then(|| mac
!()); // don't lint function in macro expansion
36 Some(1).map(closure_mac
!()); // don't lint closure in macro expansion
37 let _
: Option
<Vec
<u8>> = true.then(|| vec
![]); // special case vec!
38 let d
= Some(1u8).map(|a
| foo((|b
| foo2(b
))(a
))); //is adjusted?
39 all(&[1, 2, 3], &&2, |x
, y
| below(x
, y
)); //is adjusted
41 Some(1u8).map(|a
| unsafe_fn(a
)); // unsafe fn
45 let e
= Some(1u8).map(|a
| divergent(a
));
46 let e
= Some(1u8).map(|a
| generic(a
));
47 let e
= Some(1u8).map(generic
);
49 let a
: Option
<Box
<dyn (::std
::ops
::Deref
<Target
= [i32]>)>> =
50 Some(vec
![1i32, 2]).map(|v
| -> Box
<dyn (::std
::ops
::Deref
<Target
= [i32]>)> { Box::new(v) }
);
53 let _
: Option
<Vec
<u32>> = Some(0).map(|_
| vec
![]);
57 fn trait_foo(self) -> bool
;
58 fn trait_foo_ref(&self) -> bool
;
61 struct TestStruct
<'a
> {
65 impl<'a
> TestStruct
<'a
> {
66 fn foo(self) -> bool
{
69 unsafe fn foo_unsafe(self) -> bool
{
74 impl<'a
> TestTrait
for TestStruct
<'a
> {
75 fn trait_foo(self) -> bool
{
78 fn trait_foo_ref(&self) -> bool
{
83 impl<'a
> std
::ops
::Deref
for TestStruct
<'a
> {
85 fn deref(&self) -> &char {
90 fn test_redundant_closures_containing_method_calls() {
92 let e
= Some(TestStruct { some_ref: &i }
).map(|a
| a
.foo());
93 let e
= Some(TestStruct { some_ref: &i }
).map(TestStruct
::foo
);
94 let e
= Some(TestStruct { some_ref: &i }
).map(|a
| a
.trait_foo());
95 let e
= Some(TestStruct { some_ref: &i }
).map(|a
| a
.trait_foo_ref());
96 let e
= Some(TestStruct { some_ref: &i }
).map(TestTrait
::trait_foo
);
97 let e
= Some(&mut vec
![1, 2, 3]).map(|v
| v
.clear());
98 let e
= Some(&mut vec
![1, 2, 3]).map(std
::vec
::Vec
::clear
);
100 let e
= Some(TestStruct { some_ref: &i }
).map(|a
| a
.foo_unsafe());
102 let e
= Some("str").map(|s
| s
.to_string());
103 let e
= Some("str").map(str::to_string
);
104 let e
= Some('a'
).map(|s
| s
.to_uppercase());
105 let e
= Some('a'
).map(char::to_uppercase
);
106 let e
: std
::vec
::Vec
<usize> = vec
!['a'
, 'b'
, 'c'
].iter().map(|c
| c
.len_utf8()).collect();
107 let e
: std
::vec
::Vec
<char> = vec
!['a'
, 'b'
, 'c'
].iter().map(|c
| c
.to_ascii_uppercase()).collect();
108 let e
: std
::vec
::Vec
<char> = vec
!['a'
, 'b'
, 'c'
].iter().map(char::to_ascii_uppercase
).collect();
109 let p
= Some(PathBuf
::new());
110 let e
= p
.as_ref().and_then(|s
| s
.to_str());
111 let c
= Some(TestStruct { some_ref: &i }
)
113 .map(|c
| c
.to_ascii_uppercase());
115 fn test_different_borrow_levels
<T
>(t
: &[&T
])
119 t
.iter().filter(|x
| x
.trait_foo_ref());
120 t
.iter().map(|x
| x
.trait_foo_ref());
123 let mut some
= Some(|x
| x
* x
);
124 let arr
= [Ok(1), Err(2)];
125 let _
: Vec
<_
> = arr
.iter().map(|x
| x
.map_err(|e
| some
.take().unwrap()(e
))).collect();
128 struct Thunk
<T
>(Box
<dyn FnMut() -> T
>);
131 fn new
<F
: '
static + FnOnce() -> T
>(f
: F
) -> Thunk
<T
> {
132 let mut option
= Some(f
);
133 // This should not trigger redundant_closure (#1439)
134 Thunk(Box
::new(move || option
.take().unwrap()()))
137 fn unwrap(self) -> T
{
138 let Thunk(mut f
) = self;
144 let thunk
= Thunk
::new(|| println
!("Hello, world!"));
157 fn foo2(_
: u8) -> u8 {
161 fn all
<X
, F
>(x
: &[X
], y
: &X
, f
: F
) -> bool
163 F
: Fn(&X
, &X
) -> bool
,
165 x
.iter().all(|e
| f(e
, y
))
168 fn below(x
: &u8, y
: &u8) -> bool
{
172 unsafe fn unsafe_fn(_
: u8) {}
174 fn divergent(_
: u8) -> ! {
178 fn generic
<T
>(_
: T
) -> u8 {
182 fn passes_fn_mut(mut x
: Box
<dyn FnMut()>) {
183 requires_fn_once(|| x());
185 fn requires_fn_once
<T
: FnOnce()>(_
: T
) {}
187 fn test_redundant_closure_with_function_pointer() {
188 type FnPtrType
= fn(u8);
189 let foo_ptr
: FnPtrType
= foo
;
190 let a
= Some(1u8).map(|a
| foo_ptr(a
));
193 fn test_redundant_closure_with_another_closure() {
194 let closure
= |a
| println
!("{}", a
);
195 let a
= Some(1u8).map(|a
| closure(a
));
198 fn make_lazy(f
: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {
199 // Currently f is called when result of make_lazy is called.
200 // If the closure is removed, f will be called when make_lazy itself is
201 // called. This changes semantics, so the closure must stay.
202 Box
::new(move |x
| f()(x
))
205 fn call
<F
: FnOnce(&mut String
) -> String
>(f
: F
) -> String
{
206 f(&mut "Hello".to_owned())
208 fn test_difference_in_mutability() {
213 impl std
::ops
::Deref
for Bar
{
215 fn deref(&self) -> &str {
220 fn test_deref_with_trait_method() {
221 let _
= [Bar
].iter().map(|s
| s
.to_string()).collect
::<Vec
<_
>>();
224 fn mutable_closure_used_again(x
: Vec
<i32>, y
: Vec
<i32>, z
: Vec
<i32>) {
225 let mut res
= Vec
::new();
226 let mut add_to_res
= |n
| res
.push(n
);
227 x
.into_iter().for_each(|x
| add_to_res(x
));
228 y
.into_iter().for_each(|x
| add_to_res(x
));
229 z
.into_iter().for_each(|x
| add_to_res(x
));
232 fn mutable_closure_in_loop() {
234 let mut closure
= |n
| value
+= n
;
236 Some(1).map(|n
| closure(n
));