Skip to content

Commit 4e899e1

Browse files
authored
unnecessary_map_or: do not consume the comparison value if it does not implement Copy (rust-lang#14207)
Fix rust-lang#14201 changelog: [`unnecessary_map_or`]: do not consume the comparison value if it does not implement `Copy`
2 parents 823b818 + f826193 commit 4e899e1

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

clippy_lints/src/methods/unnecessary_map_or.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
55
use clippy_utils::msrvs::{self, Msrv};
66
use clippy_utils::sugg::{Sugg, make_binop};
7-
use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
7+
use clippy_utils::ty::{get_type_diagnostic_name, implements_trait, is_copy};
88
use clippy_utils::visitors::is_local_used;
99
use clippy_utils::{get_parent_expr, is_from_proc_macro, path_to_local_id};
1010
use rustc_ast::LitKind::Bool;
@@ -81,9 +81,11 @@ pub(super) fn check<'a>(
8181
&& (path_to_local_id(l, hir_id) ^ path_to_local_id(r, hir_id))
8282
&& !is_local_used(cx, non_binding_location, hir_id)
8383
&& let typeck_results = cx.typeck_results()
84-
&& typeck_results.expr_ty(l) == typeck_results.expr_ty(r)
84+
&& let l_ty = typeck_results.expr_ty(l)
85+
&& l_ty == typeck_results.expr_ty(r)
8586
&& let Some(partial_eq) = cx.tcx.get_diagnostic_item(sym::PartialEq)
8687
&& implements_trait(cx, recv_ty, partial_eq, &[recv_ty.into()])
88+
&& is_copy(cx, l_ty)
8789
{
8890
let wrap = variant.variant_name();
8991

tests/ui/unnecessary_map_or.fixed

+6
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,9 @@ impl std::ops::Deref for S {
9999
fn with_deref(o: &S) -> bool {
100100
o.is_none_or(|n| n > 5)
101101
}
102+
103+
fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
104+
let x = a.is_some_and(|a| a == *s);
105+
let y = b.is_none_or(|b| b == *s);
106+
x && y
107+
}

tests/ui/unnecessary_map_or.rs

+6
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,9 @@ impl std::ops::Deref for S {
102102
fn with_deref(o: &S) -> bool {
103103
o.map_or(true, |n| n > 5)
104104
}
105+
106+
fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
107+
let x = a.map_or(false, |a| a == *s);
108+
let y = b.map_or(true, |b| b == *s);
109+
x && y
110+
}

tests/ui/unnecessary_map_or.stderr

+25-1
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,29 @@ LL - o.map_or(true, |n| n > 5)
287287
LL + o.is_none_or(|n| n > 5)
288288
|
289289

290-
error: aborting due to 24 previous errors
290+
error: this `map_or` can be simplified
291+
--> tests/ui/unnecessary_map_or.rs:107:13
292+
|
293+
LL | let x = a.map_or(false, |a| a == *s);
294+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295+
|
296+
help: use is_some_and instead
297+
|
298+
LL - let x = a.map_or(false, |a| a == *s);
299+
LL + let x = a.is_some_and(|a| a == *s);
300+
|
301+
302+
error: this `map_or` can be simplified
303+
--> tests/ui/unnecessary_map_or.rs:108:13
304+
|
305+
LL | let y = b.map_or(true, |b| b == *s);
306+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
307+
|
308+
help: use is_none_or instead
309+
|
310+
LL - let y = b.map_or(true, |b| b == *s);
311+
LL + let y = b.is_none_or(|b| b == *s);
312+
|
313+
314+
error: aborting due to 26 previous errors
291315

0 commit comments

Comments
 (0)