about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlejandra González <blyxyas@gmail.com>2025-01-26 18:06:49 +0000
committerGitHub <noreply@github.com>2025-01-26 18:06:49 +0000
commit057f5b36f522be6c746290f7bb6b1a6ba6ec9415 (patch)
tree7d5c3dfeb85ed069d610d2200ad5a00b14b9cb34
parente84d60daecfe59b6cfaac73fe5e0489cf0b486f2 (diff)
parent27592e3ec828caa224112bb1e08455ca461687f9 (diff)
downloadrust-057f5b36f522be6c746290f7bb6b1a6ba6ec9415.tar.gz
rust-057f5b36f522be6c746290f7bb6b1a6ba6ec9415.zip
Make `unnecessary_map_or` work with ref and `Deref` to `Option`/`Result` (#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 #14023

**Note:** this patch must be merged after #13998 – only the second
commit must be reviewed, the first one repeats the patch in #13998 for
mergeability reasons.
-rw-r--r--clippy_lints/src/methods/unnecessary_map_or.rs2
-rw-r--r--tests/ui/unnecessary_map_or.fixed17
-rw-r--r--tests/ui/unnecessary_map_or.rs17
-rw-r--r--tests/ui/unnecessary_map_or.stderr38
4 files changed, 72 insertions, 2 deletions
diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs
index 210e7f77930..6dea1506d0e 100644
--- a/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -48,7 +48,7 @@ pub(super) fn check<'a>(
         return;
     };
 
-    let recv_ty = cx.typeck_results().expr_ty(recv);
+    let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
 
     let Bool(def_bool) = def_kind.node else {
         return;
diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed
index efea28e7045..5a6e77a06b8 100644
--- a/tests/ui/unnecessary_map_or.fixed
+++ b/tests/ui/unnecessary_map_or.fixed
@@ -82,3 +82,20 @@ 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)
+}
+
+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)
+}
diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs
index 05a0ca816ef..5ba63121659 100644
--- a/tests/ui/unnecessary_map_or.rs
+++ b/tests/ui/unnecessary_map_or.rs
@@ -85,3 +85,20 @@ 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)
+}
+
+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)
+}
diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr
index baa490871e3..2ae327f0bf8 100644
--- a/tests/ui/unnecessary_map_or.stderr
+++ b/tests/ui/unnecessary_map_or.stderr
@@ -251,5 +251,41 @@ help: use a standard comparison instead
 LL |     let _ = r == Ok(8);
    |             ~~~~~~~~~~
 
-error: aborting due to 21 previous errors
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:90:5
+   |
+LL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+LL +     o.is_none_or(|n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:90:34
+   |
+LL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+LL +     o.map_or(true, |n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:103:5
+   |
+LL |     o.map_or(true, |n| n > 5)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5)
+LL +     o.is_none_or(|n| n > 5)
+   |
+
+error: aborting due to 24 previous errors