Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 057f5b3

Browse files
authored
Make unnecessary_map_or work with ref and Deref to Option/Result (rust-lang#14024)
Receivers which are references to `Option` and `Result`, or who implement `Deref` to one of those types, will be linted as well. changelog: [`unnecessary_map_or`]: work with ref and `Deref` to `Option` and `Result` as well Fixes rust-lang#14023 **Note:** this patch must be merged after rust-lang#13998 – only the second commit must be reviewed, the first one repeats the patch in rust-lang#13998 for mergeability reasons.
2 parents e84d60d + 27592e3 commit 057f5b3

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

clippy_lints/src/methods/unnecessary_map_or.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub(super) fn check<'a>(
4848
return;
4949
};
5050

51-
let recv_ty = cx.typeck_results().expr_ty(recv);
51+
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
5252

5353
let Bool(def_bool) = def_kind.node else {
5454
return;

tests/ui/unnecessary_map_or.fixed

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,20 @@ fn msrv_1_81() {
8282
// is_none_or added in 1.82.0
8383
let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
8484
}
85+
86+
fn with_refs(o: &mut Option<u32>) -> bool {
87+
o.is_none_or(|n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)
88+
}
89+
90+
struct S;
91+
92+
impl std::ops::Deref for S {
93+
type Target = Option<u32>;
94+
fn deref(&self) -> &Self::Target {
95+
&Some(0)
96+
}
97+
}
98+
99+
fn with_deref(o: &S) -> bool {
100+
o.is_none_or(|n| n > 5)
101+
}

tests/ui/unnecessary_map_or.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,20 @@ fn msrv_1_81() {
8585
// is_none_or added in 1.82.0
8686
let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
8787
}
88+
89+
fn with_refs(o: &mut Option<u32>) -> bool {
90+
o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
91+
}
92+
93+
struct S;
94+
95+
impl std::ops::Deref for S {
96+
type Target = Option<u32>;
97+
fn deref(&self) -> &Self::Target {
98+
&Some(0)
99+
}
100+
}
101+
102+
fn with_deref(o: &S) -> bool {
103+
o.map_or(true, |n| n > 5)
104+
}

tests/ui/unnecessary_map_or.stderr

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,5 +251,41 @@ help: use a standard comparison instead
251251
LL | let _ = r == Ok(8);
252252
| ~~~~~~~~~~
253253

254-
error: aborting due to 21 previous errors
254+
error: this `map_or` can be simplified
255+
--> tests/ui/unnecessary_map_or.rs:90:5
256+
|
257+
LL | o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
258+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
259+
|
260+
help: use is_none_or instead
261+
|
262+
LL - o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
263+
LL + o.is_none_or(|n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
264+
|
265+
266+
error: this `map_or` can be simplified
267+
--> tests/ui/unnecessary_map_or.rs:90:34
268+
|
269+
LL | o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
270+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
271+
|
272+
help: use is_none_or instead
273+
|
274+
LL - o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
275+
LL + o.map_or(true, |n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)
276+
|
277+
278+
error: this `map_or` can be simplified
279+
--> tests/ui/unnecessary_map_or.rs:103:5
280+
|
281+
LL | o.map_or(true, |n| n > 5)
282+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
283+
|
284+
help: use is_none_or instead
285+
|
286+
LL - o.map_or(true, |n| n > 5)
287+
LL + o.is_none_or(|n| n > 5)
288+
|
289+
290+
error: aborting due to 24 previous errors
255291

0 commit comments

Comments
 (0)