//@aux-build:option_helpers.rs #![warn(clippy::manual_is_variant_and)] #[macro_use] extern crate option_helpers; struct Foo(T); impl Foo { fn map bool>(self, mut f: F) -> Option { Some(f(self.0)) } } fn foo() -> Option { Some(true) } macro_rules! some_true { () => { Some(true) }; } macro_rules! some_false { () => { Some(false) }; } macro_rules! mac { (some $e:expr) => { Some($e) }; (some_map $e:expr) => { Some($e).map(|x| x % 2 == 0) }; (map $e:expr) => { $e.map(|x| x % 2 == 0) }; (eq $a:expr, $b:expr) => { $a == $b }; } #[rustfmt::skip] fn option_methods() { let opt = Some(1); // Check for `option.map(_).unwrap_or_default()` use. // Single line case. let _ = opt.is_some_and(|x| x > 1); // Multi-line cases. let _ = opt.is_some_and(|x| { //~^ manual_is_variant_and x > 1 }); let _ = opt.is_some_and(|x| x > 1); //~^ manual_is_variant_and let _ = opt .is_some_and(|x| x > 1); let _ = Some(2).is_some_and(|x| x % 2 == 0); //~^ manual_is_variant_and let _ = Some(2).is_none_or(|x| x % 2 != 0); //~^ manual_is_variant_and let _ = Some(2).is_some_and(|x| x % 2 == 0); //~^ manual_is_variant_and let _ = Some(2).is_none_or(|x| x % 2 == 0); //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = opt.map(|x| x + 1).unwrap_or_default(); let opt2 = Some('a'); let _ = opt2.is_some_and(char::is_alphanumeric); // should lint //~^ manual_is_variant_and let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint // Should not lint. let _ = Foo::(0).map(|x| x.is_multiple_of(2)) == Some(true); let _ = Some(2).map(|x| x % 2 == 0) != foo(); let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true)); let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true); let _ = mac!(some_map 2) == Some(true); let _ = mac!(map Some(2)) == Some(true); } #[rustfmt::skip] fn result_methods() { let res: Result = Ok(1); // multi line cases let _ = res.is_ok_and(|x| { //~^ manual_is_variant_and x > 1 }); let _ = res.is_ok_and(|x| x > 1); let _ = Ok::(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and let _ = !Ok::(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and let _ = !Ok::(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = res.map(|x| x + 1).unwrap_or_default(); let res2: Result = Ok('a'); let _ = res2.is_ok_and(char::is_alphanumeric); // should lint //~^ manual_is_variant_and let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint } fn main() { option_methods(); result_methods(); } fn issue15202() { let xs = [None, Some(b'_'), Some(b'1')]; for x in xs { let a1 = x.is_none_or(|b| !b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_none_or(|b| !b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = x.is_none_or(|b| b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_none_or(|b| b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = x.is_some_and(|b| b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_some_and(|b| b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = x.is_some_and(|b| !b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_some_and(|b| !b.is_ascii_digit()); assert_eq!(a1, a2); } let xs = [Err("foo"), Ok(b'_'), Ok(b'1')]; for x in xs { let a1 = !x.is_ok_and(|b| b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = !x.is_ok_and(|b| b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = !x.is_ok_and(|b| !b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = !x.is_ok_and(|b| !b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = x.is_ok_and(|b| b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_ok_and(|b| b.is_ascii_digit()); assert_eq!(a1, a2); } for x in xs { let a1 = x.is_ok_and(|b| !b.is_ascii_digit()); //~^ manual_is_variant_and let a2 = x.is_ok_and(|b| !b.is_ascii_digit()); assert_eq!(a1, a2); } } mod with_func { fn iad(b: u8) -> bool { b.is_ascii_digit() } fn check_option(b: Option) { let a1 = b.is_some_and(iad); //~^ manual_is_variant_and let a2 = b.is_some_and(iad); assert_eq!(a1, a2); let a1 = b.is_some_and(|x| !iad(x)); //~^ manual_is_variant_and let a2 = b.is_some_and(|x| !iad(x)); assert_eq!(a1, a2); let a1 = b.is_none_or(|x| !iad(x)); //~^ manual_is_variant_and let a2 = b.is_none_or(|x| !iad(x)); assert_eq!(a1, a2); let a1 = b.is_none_or(iad); //~^ manual_is_variant_and let a2 = b.is_none_or(iad); assert_eq!(a1, a2); } fn check_result(b: Result) { let a1 = b.is_ok_and(iad); //~^ manual_is_variant_and let a2 = b.is_ok_and(iad); assert_eq!(a1, a2); let a1 = b.is_ok_and(|x| !iad(x)); //~^ manual_is_variant_and let a2 = b.is_ok_and(|x| !iad(x)); assert_eq!(a1, a2); let a1 = !b.is_ok_and(iad); //~^ manual_is_variant_and let a2 = !b.is_ok_and(iad); assert_eq!(a1, a2); let a1 = !b.is_ok_and(|x| !iad(x)); //~^ manual_is_variant_and let a2 = !b.is_ok_and(|x| !iad(x)); assert_eq!(a1, a2); } }