| //@aux-build:proc_macros.rs | |
| #![warn(clippy::unnecessary_map_or)] | |
| #![allow( | |
| clippy::no_effect, | |
| clippy::eq_op, | |
| clippy::unnecessary_lazy_evaluations, | |
| clippy::nonminimal_bool, | |
| clippy::manual_assert_eq | |
| )] | |
| #[clippy::msrv = "1.70.0"] | |
| #[macro_use] | |
| extern crate proc_macros; | |
| fn main() { | |
| // should trigger | |
| let _ = Some(5) == Some(5); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5) != Some(5); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5) == Some(5); | |
| let _ = Some(5).is_some_and(|n| { | |
| //~^ unnecessary_map_or | |
| let _ = n; | |
| 6 >= 5 | |
| }); | |
| let _ = Some(vec![5]).is_some_and(|n| n == [5]); | |
| //~^ unnecessary_map_or | |
| let _ = Some(vec![1]).is_some_and(|n| vec![2] == n); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_some_and(|n| n == n); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 }); | |
| //~^ unnecessary_map_or | |
| let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]); | |
| //~^ unnecessary_map_or | |
| let _ = Ok::<i32, i32>(5) == Ok(5); | |
| //~^ unnecessary_map_or | |
| let _ = (Some(5) == Some(5)).then(|| 1); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_none_or(|n| n == 5); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_none_or(|n| 5 == n); | |
| //~^ unnecessary_map_or | |
| let _ = !(Some(5) == Some(5)); | |
| //~^ unnecessary_map_or | |
| let _ = (Some(5) == Some(5)) || false; | |
| //~^ unnecessary_map_or | |
| let _ = (Some(5) == Some(5)) as usize; | |
| //~^ unnecessary_map_or | |
| macro_rules! x { | |
| () => { | |
| Some(1) | |
| }; | |
| } | |
| // methods lints dont fire on macros | |
| let _ = x!().map_or(false, |n| n == 1); | |
| let _ = x!().map_or(false, |n| n == vec![1][0]); | |
| msrv_1_69(); | |
| external! { | |
| let _ = Some(5).map_or(false, |n| n == 5); | |
| } | |
| with_span! { | |
| let _ = Some(5).map_or(false, |n| n == 5); | |
| } | |
| // check for presence of PartialEq, and alter suggestion to use `is_ok_and` if absent | |
| struct S; | |
| let r: Result<i32, S> = Ok(3); | |
| let _ = r.is_ok_and(|x| x == 7); | |
| //~^ unnecessary_map_or | |
| // lint constructs that are not comparisons as well | |
| let func = |_x| true; | |
| let r: Result<i32, S> = Ok(3); | |
| let _ = r.is_ok_and(func); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_some_and(func); | |
| //~^ unnecessary_map_or | |
| let _ = Some(5).is_none_or(func); | |
| //~^ unnecessary_map_or | |
| #[derive(PartialEq)] | |
| struct S2; | |
| let r: Result<i32, S2> = Ok(4); | |
| let _ = r == Ok(8); | |
| //~^ unnecessary_map_or | |
| // do not lint `Result::map_or(true, …)` | |
| let r: Result<i32, S2> = Ok(4); | |
| let _ = r.map_or(true, |x| x == 8); | |
| } | |
| #[clippy::msrv = "1.69.0"] | |
| fn msrv_1_69() { | |
| // is_some_and added in 1.70.0 | |
| let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); | |
| } | |
| #[clippy::msrv = "1.81.0"] | |
| fn msrv_1_81() { | |
| // is_none_or added in 1.82.0 | |
| let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 }); | |
| } | |
| fn with_refs(o: &mut Option<u32>) -> bool { | |
| o.is_none_or(|n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5) | |
| //~^ unnecessary_map_or | |
| //~| unnecessary_map_or | |
| } | |
| struct S; | |
| impl std::ops::Deref for S { | |
| type Target = Option<u32>; | |
| fn deref(&self) -> &Self::Target { | |
| &Some(0) | |
| } | |
| } | |
| fn with_deref(o: &S) -> bool { | |
| o.is_none_or(|n| n > 5) | |
| //~^ unnecessary_map_or | |
| } | |
| fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool { | |
| let x = a.is_some_and(|a| a == *s); | |
| //~^ unnecessary_map_or | |
| let y = b.is_none_or(|b| b == *s); | |
| //~^ unnecessary_map_or | |
| x && y | |
| } | |
| fn issue14714() { | |
| assert!(Some("test") == Some("test")); | |
| //~^ unnecessary_map_or | |
| // even though we're in a macro context, we still need to parenthesise because of the `then` | |
| assert!((Some("test") == Some("test")).then(|| 1).is_some()); | |
| //~^ unnecessary_map_or | |
| // method lints don't fire on macros | |
| macro_rules! m { | |
| ($x:expr) => { | |
| // should become !($x == Some(1)) | |
| let _ = !$x.map_or(false, |v| v == 1); | |
| // should become $x == Some(1) | |
| let _ = $x.map_or(false, |v| v == 1); | |
| }; | |
| } | |
| m!(Some(5)); | |
| } | |
| fn issue15180() { | |
| let s = std::sync::Mutex::new(Some("foo")); | |
| _ = s.lock().unwrap().is_some_and(|s| s == "foo"); | |
| //~^ unnecessary_map_or | |
| let s = &&&&Some("foo"); | |
| _ = s.is_some_and(|s| s == "foo"); | |
| //~^ unnecessary_map_or | |
| } |