unused,
clippy::no_effect,
clippy::redundant_closure_call,
- clippy::many_single_char_names,
clippy::needless_pass_by_value,
- clippy::option_map_unit_fn
-)]
-#![warn(
- clippy::redundant_closure,
- clippy::redundant_closure_for_method_calls,
+ clippy::option_map_unit_fn,
clippy::needless_borrow
)]
+#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
+
+use std::path::{Path, PathBuf};
-use std::path::PathBuf;
+macro_rules! mac {
+ () => {
+ foobar()
+ };
+}
+
+macro_rules! closure_mac {
+ () => {
+ |n| foo(n)
+ };
+}
fn main() {
let a = Some(1u8).map(foo);
- meta(foo);
let c = Some(1u8).map(|a| {1+2; foo}(a));
- 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
+ true.then(|| mac!()); // don't lint function in macro expansion
+ Some(1).map(closure_mac!()); // don't lint closure in macro expansion
+ let _: Option<Vec<u8>> = true.then(std::vec::Vec::new); // special case vec!
+ let d = Some(1u8).map(|a| foo(foo2(a))); //is adjusted?
+ all(&[1, 2, 3], &&2, below); //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(divergent);
let e = Some(1u8).map(generic);
let e = Some(1u8).map(generic);
// See #515
let a: Option<Box<dyn (::std::ops::Deref<Target = [i32]>)>> =
Some(vec![1i32, 2]).map(|v| -> Box<dyn (::std::ops::Deref<Target = [i32]>)> { Box::new(v) });
+
+ // issue #7224
+ let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);
}
trait TestTrait {
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<usize> = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect();
let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(char::to_ascii_uppercase).collect();
- let e: std::vec::Vec<char> = 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 e = Some(PathBuf::new()).as_ref().and_then(|s| s.to_str());
let c = Some(TestStruct { some_ref: &i })
.as_ref()
.map(|c| c.to_ascii_uppercase());
t.iter().filter(|x| x.trait_foo_ref());
t.iter().map(|x| x.trait_foo_ref());
}
-
- let mut some = Some(|x| x * x);
- let arr = [Ok(1), Err(2)];
- let _: Vec<_> = arr.iter().map(|x| x.map_err(|e| some.take().unwrap()(e))).collect();
}
struct Thunk<T>(Box<dyn FnMut() -> T>);
thunk.unwrap()
}
-fn meta<F>(f: F)
-where
- F: Fn(u8),
-{
- f(1u8)
-}
-
fn foo(_: u8) {}
fn foo2(_: u8) -> u8 {
}
fn passes_fn_mut(mut x: Box<dyn FnMut()>) {
- requires_fn_once(|| x());
+ requires_fn_once(x);
}
fn requires_fn_once<T: FnOnce()>(_: T) {}
fn test_deref_with_trait_method() {
let _ = [Bar].iter().map(|s| s.to_string()).collect::<Vec<_>>();
}
+
+fn mutable_closure_used_again(x: Vec<i32>, y: Vec<i32>, z: Vec<i32>) {
+ let mut res = Vec::new();
+ let mut add_to_res = |n| res.push(n);
+ x.into_iter().for_each(&mut add_to_res);
+ y.into_iter().for_each(&mut add_to_res);
+ z.into_iter().for_each(add_to_res);
+}
+
+fn mutable_closure_in_loop() {
+ let mut value = 0;
+ let mut closure = |n| value += n;
+ for _ in 0..5 {
+ Some(1).map(&mut closure);
+ }
+}
+
+fn late_bound_lifetimes() {
+ fn take_asref_path<P: AsRef<Path>>(path: P) {}
+
+ fn map_str<F>(thunk: F)
+ where
+ F: FnOnce(&str),
+ {
+ }
+
+ fn map_str_to_path<F>(thunk: F)
+ where
+ F: FnOnce(&str) -> &Path,
+ {
+ }
+ map_str(|s| take_asref_path(s));
+ map_str_to_path(std::convert::AsRef::as_ref);
+}
+
+mod type_param_bound {
+ trait Trait {
+ fn fun();
+ }
+
+ fn take<T: 'static>(_: T) {}
+
+ fn test<X: Trait>() {
+ // don't lint, but it's questionable that rust requires a cast
+ take(|| X::fun());
+ take(X::fun as fn());
+ }
+}
+
+// #8073 Don't replace closure with `Arc<F>` or `Rc<F>`
+fn arc_fp() {
+ let rc = std::rc::Rc::new(|| 7);
+ let arc = std::sync::Arc::new(|n| n + 1);
+ let ref_arc = &std::sync::Arc::new(|_| 5);
+
+ true.then(|| rc());
+ (0..5).map(|n| arc(n));
+ Some(4).map(|n| ref_arc(n));
+}