Skip to content

Commit c69905a

Browse files
committed
Do not remove method call if type is adjusted
Propose to replace `x.map_or(false, |y| y == z)` by `x == Some(z)` only if `x` is not adjusted. Otherwise, the type of `x` in the comparaison may not be the expected one, as it may be the product of an auto-deref.
1 parent b57bf6b commit c69905a

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

clippy_lints/src/methods/unnecessary_map_or.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ pub(super) fn check<'a>(
6262

6363
let ext_def_span = def.span.until(map.span);
6464

65-
let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind
65+
let (sugg, method, applicability) = if cx.typeck_results().expr_adjustments(recv).is_empty()
66+
&& let ExprKind::Closure(map_closure) = map.kind
6667
&& let closure_body = cx.tcx.hir_body(map_closure.body)
6768
&& let closure_body_value = closure_body.value.peel_blocks()
6869
&& let ExprKind::Binary(op, l, r) = closure_body_value.kind

tests/ui/unnecessary_map_or.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
130130
//~^ unnecessary_map_or
131131
x && y
132132
}
133+
134+
fn issue15180() {
135+
let s = std::sync::Mutex::new(Some("foo"));
136+
_ = s.lock().unwrap().is_some_and(|s| s == "foo");
137+
//~^ unnecessary_map_or
138+
139+
let s = &&&&Some("foo");
140+
_ = s.is_some_and(|s| s == "foo");
141+
//~^ unnecessary_map_or
142+
}

tests/ui/unnecessary_map_or.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
134134
//~^ unnecessary_map_or
135135
x && y
136136
}
137+
138+
fn issue15180() {
139+
let s = std::sync::Mutex::new(Some("foo"));
140+
_ = s.lock().unwrap().map_or(false, |s| s == "foo");
141+
//~^ unnecessary_map_or
142+
143+
let s = &&&&Some("foo");
144+
_ = s.map_or(false, |s| s == "foo");
145+
//~^ unnecessary_map_or
146+
}

tests/ui/unnecessary_map_or.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,5 +326,29 @@ LL - let y = b.map_or(true, |b| b == *s);
326326
LL + let y = b.is_none_or(|b| b == *s);
327327
|
328328

329-
error: aborting due to 26 previous errors
329+
error: this `map_or` can be simplified
330+
--> tests/ui/unnecessary_map_or.rs:140:9
331+
|
332+
LL | _ = s.lock().unwrap().map_or(false, |s| s == "foo");
333+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
334+
|
335+
help: use is_some_and instead
336+
|
337+
LL - _ = s.lock().unwrap().map_or(false, |s| s == "foo");
338+
LL + _ = s.lock().unwrap().is_some_and(|s| s == "foo");
339+
|
340+
341+
error: this `map_or` can be simplified
342+
--> tests/ui/unnecessary_map_or.rs:144:9
343+
|
344+
LL | _ = s.map_or(false, |s| s == "foo");
345+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
346+
|
347+
help: use is_some_and instead
348+
|
349+
LL - _ = s.map_or(false, |s| s == "foo");
350+
LL + _ = s.is_some_and(|s| s == "foo");
351+
|
352+
353+
error: aborting due to 28 previous errors
330354

0 commit comments

Comments
 (0)