1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
//@aux-build:proc_macros.rs
#![warn(clippy::unnecessary_map_or)]
#![allow(clippy::no_effect)]
#![allow(clippy::eq_op)]
#![allow(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::nonminimal_bool)]
#[clippy::msrv = "1.70.0"]
#[macro_use]
extern crate proc_macros;
fn main() {
// should trigger
let _ = Some(5).map_or(false, |n| n == 5);
//~^ unnecessary_map_or
let _ = Some(5).map_or(true, |n| n != 5);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| {
//~^ unnecessary_map_or
let _ = 1;
n == 5
});
let _ = Some(5).map_or(false, |n| {
//~^ unnecessary_map_or
let _ = n;
6 >= 5
});
let _ = Some(vec![5]).map_or(false, |n| n == [5]);
//~^ unnecessary_map_or
let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| n == n);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
//~^ unnecessary_map_or
let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
//~^ unnecessary_map_or
let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
//~^ unnecessary_map_or
let _ = Some(5).map_or(true, |n| n == 5);
//~^ unnecessary_map_or
let _ = Some(5).map_or(true, |n| 5 == n);
//~^ unnecessary_map_or
let _ = !Some(5).map_or(false, |n| n == 5);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| n == 5) || false;
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, |n| n == 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.map_or(false, |x| x == 7);
//~^ unnecessary_map_or
// lint constructs that are not comparaisons as well
let func = |_x| true;
let r: Result<i32, S> = Ok(3);
let _ = r.map_or(false, func);
//~^ unnecessary_map_or
let _ = Some(5).map_or(false, func);
//~^ unnecessary_map_or
let _ = Some(5).map_or(true, func);
//~^ unnecessary_map_or
#[derive(PartialEq)]
struct S2;
let r: Result<i32, S2> = Ok(4);
let _ = r.map_or(false, |x| x == 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.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |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.map_or(true, |n| n > 5)
//~^ unnecessary_map_or
}
fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
let x = a.map_or(false, |a| a == *s);
//~^ unnecessary_map_or
let y = b.map_or(true, |b| b == *s);
//~^ unnecessary_map_or
x && y
}
fn issue14714() {
assert!(Some("test").map_or(false, |x| x == "test"));
//~^ unnecessary_map_or
// even though we're in a macro context, we still need to parenthesise because of the `then`
assert!(Some("test").map_or(false, |x| x == "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().map_or(false, |s| s == "foo");
//~^ unnecessary_map_or
let s = &&&&Some("foo");
_ = s.map_or(false, |s| s == "foo");
//~^ unnecessary_map_or
}
|