From 6f8aee0157bb00448eb1858a38ef5bffe1dd8ede Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Tue, 28 Oct 2025 20:30:40 +0100 Subject: [PATCH] feat(manual_assert_eq): new lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/eta_reduction.rs | 2 +- .../src/functions/renamed_function_params.rs | 2 +- clippy_lints/src/lib.rs | 2 + clippy_lints/src/manual_assert_eq.rs | 122 ++++++++++++++++++ lintcheck/src/output.rs | 4 +- tests/ui/assertions_on_constants.rs | 1 + tests/ui/assertions_on_constants.stderr | 34 ++--- tests/ui/cmp_null.fixed | 1 + tests/ui/cmp_null.rs | 1 + tests/ui/cmp_null.stderr | 14 +- tests/ui/infinite_loops.rs | 4 +- tests/ui/manual_assert_eq.fixed | 114 ++++++++++++++++ tests/ui/manual_assert_eq.rs | 114 ++++++++++++++++ tests/ui/manual_assert_eq.stderr | 88 +++++++++++++ tests/ui/missing_asserts_for_indexing.fixed | 2 +- tests/ui/missing_asserts_for_indexing.rs | 2 +- tests/ui/panic_in_result_fn_assertions.rs | 4 +- tests/ui/panic_in_result_fn_assertions.stderr | 6 +- .../ui/panic_in_result_fn_debug_assertions.rs | 4 +- tests/ui/uninit_vec.rs | 2 +- tests/ui/unnecessary_map_or.fixed | 11 +- tests/ui/unnecessary_map_or.rs | 11 +- tests/ui/unnecessary_map_or.stderr | 60 ++++----- 25 files changed, 529 insertions(+), 78 deletions(-) create mode 100644 clippy_lints/src/manual_assert_eq.rs create mode 100644 tests/ui/manual_assert_eq.fixed create mode 100644 tests/ui/manual_assert_eq.rs create mode 100644 tests/ui/manual_assert_eq.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 816147076179..60d4cdf3608f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6878,6 +6878,7 @@ Released 2018-09-13 [`main_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#main_recursion [`manual_abs_diff`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff [`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert +[`manual_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert_eq [`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn [`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits [`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 837bf29f5f39..2908278ecc55 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -298,6 +298,7 @@ crate::main_recursion::MAIN_RECURSION_INFO, crate::manual_abs_diff::MANUAL_ABS_DIFF_INFO, crate::manual_assert::MANUAL_ASSERT_INFO, + crate::manual_assert_eq::MANUAL_ASSERT_EQ_INFO, crate::manual_async_fn::MANUAL_ASYNC_FN_INFO, crate::manual_bits::MANUAL_BITS_INFO, crate::manual_checked_ops::MANUAL_CHECKED_OPS_INFO, diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 3562200cbd92..8db543d65955 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -373,7 +373,7 @@ fn check_ty(from_ty: Ty<'_>, to_ty: Ty<'_>) -> bool { } } - assert!(from_sig.inputs_and_output.len() == to_sig.inputs_and_output.len()); + assert_eq!(from_sig.inputs_and_output.len(), to_sig.inputs_and_output.len()); from_sig .inputs_and_output .iter() diff --git a/clippy_lints/src/functions/renamed_function_params.rs b/clippy_lints/src/functions/renamed_function_params.rs index e25611d48817..2d330835a037 100644 --- a/clippy_lints/src/functions/renamed_function_params.rs +++ b/clippy_lints/src/functions/renamed_function_params.rs @@ -57,7 +57,7 @@ fn new(default_idents: &mut I1, current_idents: &mut I2) -> Self { let mut renamed: Vec<(Span, String)> = vec![]; - debug_assert!(default_idents.size_hint() == current_idents.size_hint()); + debug_assert_eq!(default_idents.size_hint(), current_idents.size_hint()); for (default_ident, current_ident) in iter::zip(default_idents, current_idents) { let has_name_to_check = |ident: Option| { ident diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 72ee5cca0397..0875982f3bbf 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -196,6 +196,7 @@ mod main_recursion; mod manual_abs_diff; mod manual_assert; +mod manual_assert_eq; mod manual_async_fn; mod manual_bits; mod manual_checked_ops; @@ -867,6 +868,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |tcx| Box::new(manual_pop_if::ManualPopIf::new(tcx, conf))), Box::new(move |_| Box::new(manual_noop_waker::ManualNoopWaker::new(conf))), Box::new(|_| Box::new(byte_char_slices::ByteCharSlice)), + Box::new(|_| Box::new(manual_assert_eq::ManualAssertEq)), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/manual_assert_eq.rs b/clippy_lints/src/manual_assert_eq.rs new file mode 100644 index 000000000000..d1770d2e95a6 --- /dev/null +++ b/clippy_lints/src/manual_assert_eq.rs @@ -0,0 +1,122 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::macros::{PanicCall, find_assert_args, root_macro_call_first_node}; +use clippy_utils::source::walk_span_to_context; +use clippy_utils::ty::implements_trait; +use clippy_utils::{is_in_const_context, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::declare_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Checks for `assert!` and `debug_assert!` that consist of only an (in)equality check + /// + /// ### Why is this bad? + /// `assert_{eq,ne}!` and `debug_assert_{eq,ne}!` achieves the same goal, and provides some + /// additional debug information + /// + /// ### Example + /// ```no_run + /// assert!(2 * 2 == 4); + /// assert!(2 * 2 != 5); + /// debug_assert!(2 * 2 == 4); + /// debug_assert!(2 * 2 != 5); + /// ``` + /// Use instead: + /// ```no_run + /// assert_eq!(2 * 2, 4); + /// assert_ne!(2 * 2, 5); + /// debug_assert_eq!(2 * 2, 4); + /// debug_assert_ne!(2 * 2, 5); + /// ``` + #[clippy::version = "1.97.0"] + pub MANUAL_ASSERT_EQ, + pedantic, + "checks for assertions consisting of an (in)equality check" +} + +declare_lint_pass!(ManualAssertEq => [MANUAL_ASSERT_EQ]); + +#[derive(Clone, Copy, PartialEq, Eq)] +enum EqKind { + Eq, + Ne, +} + +impl EqKind { + fn postfix(self) -> &'static str { + match self { + Self::Eq => "_eq", + Self::Ne => "_ne", + } + } +} + +impl LateLintPass<'_> for ManualAssertEq { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if let Some(macro_call) = root_macro_call_first_node(cx, expr) + && let macro_name = match cx.tcx.get_diagnostic_name(macro_call.def_id) { + Some(sym::assert_macro) => "assert", + Some(sym::debug_assert_macro) => "debug_assert", + _ => return, + } + && !is_in_const_context(cx) + && let Some((cond, panic_expn)) = find_assert_args(cx, expr, macro_call.expn) + // Don't lint if the user has a painstakingly written assertion message + && !matches!(panic_expn, PanicCall::Display(_) | PanicCall::Format(_)) + && let ExprKind::Binary(op, lhs, rhs) = cond.kind + && let eq_kind = match op.node { + BinOpKind::Eq => EqKind::Eq, + BinOpKind::Ne => EqKind::Ne, + _ => return, + } + && !cond.span.from_expansion() + && let Some(debug_trait) = cx.tcx.get_diagnostic_item(sym::Debug) + && let lhs_ty = cx.typeck_results().expr_ty(lhs) + && let rhs_ty = cx.typeck_results().expr_ty(rhs) + // Can't print the values unless the types implement `Debug` + && implements_trait(cx, lhs_ty, debug_trait, &[]) + && implements_trait(cx, rhs_ty, debug_trait, &[]) + // Printing raw pointers isn't very useful + && !lhs_ty.is_raw_ptr() + && !rhs_ty.is_raw_ptr() + // The output of `(debug_)assert_eq` isn't very useful when one of the sides is a constant value + && if eq_kind == EqKind::Ne { + let ecx = ConstEvalCtxt::new(cx); + ecx.eval(lhs).is_none() && ecx.eval(rhs).is_none() + } else { + true + } + { + span_lint_and_then( + cx, + MANUAL_ASSERT_EQ, + macro_call.span, + format!("used `{macro_name}!` with an equality comparison"), + |diag| { + let postfix = eq_kind.postfix(); + let new_name = format_args!("{macro_name}{postfix}"); + let msg = format!("replace it with `{new_name}!(..)`"); + + let ctxt = cond.span.ctxt(); + if let Some(lhs_span) = walk_span_to_context(lhs.span, ctxt) + && let Some(rhs_span) = walk_span_to_context(rhs.span, ctxt) + { + let macro_name_span = cx.sess().source_map().span_until_char(macro_call.span, '!'); + let eq_span = cond.span.with_lo(lhs_span.hi()).with_hi(rhs_span.lo()); + let suggestions = vec![ + (macro_name_span.shrink_to_hi(), postfix.to_string()), + (eq_span, ", ".to_string()), + ]; + + diag.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable); + } else { + diag.span_help(expr.span, msg); + } + }, + ); + } + } +} diff --git a/lintcheck/src/output.rs b/lintcheck/src/output.rs index 1ecc3f7c2494..dfba1804642e 100644 --- a/lintcheck/src/output.rs +++ b/lintcheck/src/output.rs @@ -228,8 +228,8 @@ fn print_stats(old_stats: HashMap, new_stats: HashMap<&String, us // remove duplicates from both hashmaps for (k, v) in &same_in_both_hashmaps { - assert!(old_stats_deduped.remove(k) == Some(*v)); - assert!(new_stats_deduped.remove(k) == Some(*v)); + assert_eq!(old_stats_deduped.remove(k), Some(*v)); + assert_eq!(new_stats_deduped.remove(k), Some(*v)); } println!("\nStats:"); diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs index 1c49b6e6b7b1..44bcc5c724e9 100644 --- a/tests/ui/assertions_on_constants.rs +++ b/tests/ui/assertions_on_constants.rs @@ -1,4 +1,5 @@ #![allow(non_fmt_panics, clippy::needless_bool, clippy::eq_op)] +#![expect(clippy::manual_assert_eq)] macro_rules! assert_const { ($len:expr) => { diff --git a/tests/ui/assertions_on_constants.stderr b/tests/ui/assertions_on_constants.stderr index a996c41b6942..abace40735ed 100644 --- a/tests/ui/assertions_on_constants.stderr +++ b/tests/ui/assertions_on_constants.stderr @@ -1,5 +1,5 @@ error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:10:5 + --> tests/ui/assertions_on_constants.rs:11:5 | LL | assert!(true); | ^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | assert!(true); = help: to override `-D warnings` add `#[allow(clippy::assertions_on_constants)]` error: this assertion is always `false` - --> tests/ui/assertions_on_constants.rs:13:5 + --> tests/ui/assertions_on_constants.rs:14:5 | LL | assert!(false); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | assert!(false); = help: replace this with `panic!()` or `unreachable!()` error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:16:5 + --> tests/ui/assertions_on_constants.rs:17:5 | LL | assert!(true, "true message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | assert!(true, "true message"); = help: remove the assertion error: this assertion is always `false` - --> tests/ui/assertions_on_constants.rs:19:5 + --> tests/ui/assertions_on_constants.rs:20:5 | LL | assert!(false, "false message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | assert!(false, "false message"); = help: replace this with `panic!()` or `unreachable!()` error: this assertion is always `false` - --> tests/ui/assertions_on_constants.rs:23:5 + --> tests/ui/assertions_on_constants.rs:24:5 | LL | assert!(false, "{}", msg.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | assert!(false, "{}", msg.to_uppercase()); = help: replace this with `panic!()` or `unreachable!()` error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:27:5 + --> tests/ui/assertions_on_constants.rs:28:5 | LL | assert!(B); | ^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | assert!(B); = help: consider moving this into a const block: `const { assert!(..) }` error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:31:5 + --> tests/ui/assertions_on_constants.rs:32:5 | LL | assert!(C); | ^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | assert!(C); = help: consider moving this into a const block: `const { assert!(..) }` error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:34:5 + --> tests/ui/assertions_on_constants.rs:35:5 | LL | assert!(C, "C message"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | assert!(C, "C message"); = help: consider moving this into a const block: `const { assert!(..) }` error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:37:5 + --> tests/ui/assertions_on_constants.rs:38:5 | LL | debug_assert!(true); | ^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | debug_assert!(true); = help: remove the assertion error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:45:5 + --> tests/ui/assertions_on_constants.rs:46:5 | LL | assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf"))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf"))); = help: consider moving this into a const block: `const { assert!(..) }` error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:54:19 + --> tests/ui/assertions_on_constants.rs:55:19 | LL | const _: () = assert!(true); | ^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | const _: () = assert!(true); = help: remove the assertion error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:57:5 + --> tests/ui/assertions_on_constants.rs:58:5 | LL | assert!(8 == (7 + 1)); | ^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | assert!(8 == (7 + 1)); = help: remove the assertion error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:68:5 + --> tests/ui/assertions_on_constants.rs:69:5 | LL | assert!(true); | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | assert!(true); = help: remove the assertion error: this assertion is always `true` - --> tests/ui/assertions_on_constants.rs:71:5 + --> tests/ui/assertions_on_constants.rs:72:5 | LL | assert!(8 == (7 + 1)); | ^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | assert!(8 == (7 + 1)); = help: remove the assertion error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:79:5 + --> tests/ui/assertions_on_constants.rs:80:5 | LL | assert!(C); | ^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | assert!(C); = help: consider moving this to an anonymous constant: `const _: () = { assert!(..); }` error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:90:5 + --> tests/ui/assertions_on_constants.rs:91:5 | LL | assert!(C); | ^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | assert!(C); = help: consider moving this into a const block: `const { assert!(..) }` error: this assertion has a constant value - --> tests/ui/assertions_on_constants.rs:96:5 + --> tests/ui/assertions_on_constants.rs:97:5 | LL | assert!(C); | ^^^^^^^^^^ diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed index 4a0ee439e94a..1b49549e9712 100644 --- a/tests/ui/cmp_null.fixed +++ b/tests/ui/cmp_null.fixed @@ -1,4 +1,5 @@ #![warn(clippy::cmp_null)] +#![allow(clippy::manual_assert_eq)] use std::ptr; diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index 26ea8960e5fb..35de3a14afc6 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -1,4 +1,5 @@ #![warn(clippy::cmp_null)] +#![allow(clippy::manual_assert_eq)] use std::ptr; diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index 51b98d2a2320..9831b4f6eb32 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -1,5 +1,5 @@ error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:8:8 + --> tests/ui/cmp_null.rs:9:8 | LL | if p == ptr::null() { | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` @@ -8,37 +8,37 @@ LL | if p == ptr::null() { = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:13:8 + --> tests/ui/cmp_null.rs:14:8 | LL | if ptr::null() == p { | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:21:8 + --> tests/ui/cmp_null.rs:22:8 | LL | if m == ptr::null_mut() { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:26:8 + --> tests/ui/cmp_null.rs:27:8 | LL | if ptr::null_mut() == m { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:32:13 + --> tests/ui/cmp_null.rs:33:13 | LL | let _ = x as *const () == ptr::null(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:38:19 + --> tests/ui/cmp_null.rs:39:19 | LL | debug_assert!(f != std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!f.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:56:8 + --> tests/ui/cmp_null.rs:57:8 | LL | if dot_value!(x) == ptr::null() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dot_value!(x).is_null()` diff --git a/tests/ui/infinite_loops.rs b/tests/ui/infinite_loops.rs index 88e3328d662e..c0f0087b374c 100644 --- a/tests/ui/infinite_loops.rs +++ b/tests/ui/infinite_loops.rs @@ -295,7 +295,7 @@ fn panic_like_macros_1() { } fn panic_like_macros_2() { - let mut x = 0; + let mut x: i32 = 0; loop { do_something(); @@ -310,7 +310,7 @@ fn panic_like_macros_2() { } loop { do_something(); - assert!(x % 2 == 0); + assert!(x.is_positive()); } loop { do_something(); diff --git a/tests/ui/manual_assert_eq.fixed b/tests/ui/manual_assert_eq.fixed new file mode 100644 index 000000000000..175c33e27192 --- /dev/null +++ b/tests/ui/manual_assert_eq.fixed @@ -0,0 +1,114 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_assert_eq)] +#![allow(clippy::manual_ignore_case_cmp)] // only raised before the fix +#![expect(clippy::eq_op, clippy::assertions_on_constants)] + +fn main() { + let a = "a"; + assert_eq!(a, "a".to_ascii_lowercase()); + //~^ manual_assert_eq + assert_ne!(a, "a".to_ascii_uppercase()); + //~^ manual_assert_eq + debug_assert_eq!(a, "a".to_ascii_lowercase()); + //~^ manual_assert_eq + debug_assert_ne!(a, "a".to_ascii_uppercase()); + //~^ manual_assert_eq + + // macros + let v = vec![]; + assert_eq!(v, vec![1, 2, 3]); + //~^ manual_assert_eq + assert_eq!(vec![1, 2, 3], v); + //~^ manual_assert_eq + assert_eq!(vec![1], vec![1, 2, 3]); + //~^ manual_assert_eq + + // Don't lint: has assert message + assert!(a == "a".to_ascii_lowercase(), "{a}"); + assert!(a == "a".to_ascii_lowercase(), "a==a"); + assert!(a == "a".to_ascii_lowercase(), "{a}==a"); + assert!(a != "a".to_ascii_uppercase(), "a!=A"); + debug_assert!(a == "a".to_ascii_lowercase(), "a==a"); + debug_assert!(a != "a".to_ascii_uppercase(), "a!=A"); + + // Don't lint: `!=`, and at least one of the sides is a constant value + assert!(a != "A"); + assert!("A" != a); + assert!("A" != "A"); + + // Don't lint: comparison of ptrs + fn cmp_ptrs(a: *const u8, b: *const u8) { + assert!(a == b); + } + + // Don't lint: one of the sides isn't `Debug` + { + #[derive(PartialEq)] + struct NotDebug; + + #[derive(PartialEq)] + struct NotDebug2; + + impl PartialEq for NotDebug { + fn eq(&self, other: &NotDebug2) -> bool { + unimplemented!() + } + } + impl PartialEq for NotDebug2 { + fn eq(&self, other: &NotDebug) -> bool { + unimplemented!() + } + } + + #[derive(Debug)] + struct IsDebug; + + impl PartialEq for NotDebug { + fn eq(&self, other: &IsDebug) -> bool { + unimplemented!() + } + } + impl PartialEq for IsDebug { + fn eq(&self, other: &NotDebug) -> bool { + unimplemented!() + } + } + + let nd = NotDebug; + assert!(nd == nd); + + let nd2 = NotDebug2; + assert!(nd == nd2); + assert!(nd2 == nd); + + let id = IsDebug; + assert!(id == nd); + assert!(nd == id); + } + + // Don't lint: in const context + const { + assert!(5 == 2 + 3); + } + + // Don't lint: in external macro + { + // NOTE: this only works because `root_macro_call_first_node` returns `external!`, + // which then gets rejected by the macro name check + proc_macros::external!(assert!('a' == 'b')); + proc_macros::external!({ + let some_padding_before = 'a'; + assert!('a' == 'b'); + let some_padding_after = 'b'; + }); + + // .. which also means that the following is _technically_ a FN -- but surely no one would write + // code like this (diverging/unit expression as a child expression of a macro call) + vec![(), assert!('a' == 'b'), ()]; + } +} + +// Don't lint: in const context +const _: () = { + assert!(8 == (7 + 1)); +}; diff --git a/tests/ui/manual_assert_eq.rs b/tests/ui/manual_assert_eq.rs new file mode 100644 index 000000000000..0df5518bd354 --- /dev/null +++ b/tests/ui/manual_assert_eq.rs @@ -0,0 +1,114 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_assert_eq)] +#![allow(clippy::manual_ignore_case_cmp)] // only raised before the fix +#![expect(clippy::eq_op, clippy::assertions_on_constants)] + +fn main() { + let a = "a"; + assert!(a == "a".to_ascii_lowercase()); + //~^ manual_assert_eq + assert!(a != "a".to_ascii_uppercase()); + //~^ manual_assert_eq + debug_assert!(a == "a".to_ascii_lowercase()); + //~^ manual_assert_eq + debug_assert!(a != "a".to_ascii_uppercase()); + //~^ manual_assert_eq + + // macros + let v = vec![]; + assert!(v == vec![1, 2, 3]); + //~^ manual_assert_eq + assert!(vec![1, 2, 3] == v); + //~^ manual_assert_eq + assert!(vec![1] == vec![1, 2, 3]); + //~^ manual_assert_eq + + // Don't lint: has assert message + assert!(a == "a".to_ascii_lowercase(), "{a}"); + assert!(a == "a".to_ascii_lowercase(), "a==a"); + assert!(a == "a".to_ascii_lowercase(), "{a}==a"); + assert!(a != "a".to_ascii_uppercase(), "a!=A"); + debug_assert!(a == "a".to_ascii_lowercase(), "a==a"); + debug_assert!(a != "a".to_ascii_uppercase(), "a!=A"); + + // Don't lint: `!=`, and at least one of the sides is a constant value + assert!(a != "A"); + assert!("A" != a); + assert!("A" != "A"); + + // Don't lint: comparison of ptrs + fn cmp_ptrs(a: *const u8, b: *const u8) { + assert!(a == b); + } + + // Don't lint: one of the sides isn't `Debug` + { + #[derive(PartialEq)] + struct NotDebug; + + #[derive(PartialEq)] + struct NotDebug2; + + impl PartialEq for NotDebug { + fn eq(&self, other: &NotDebug2) -> bool { + unimplemented!() + } + } + impl PartialEq for NotDebug2 { + fn eq(&self, other: &NotDebug) -> bool { + unimplemented!() + } + } + + #[derive(Debug)] + struct IsDebug; + + impl PartialEq for NotDebug { + fn eq(&self, other: &IsDebug) -> bool { + unimplemented!() + } + } + impl PartialEq for IsDebug { + fn eq(&self, other: &NotDebug) -> bool { + unimplemented!() + } + } + + let nd = NotDebug; + assert!(nd == nd); + + let nd2 = NotDebug2; + assert!(nd == nd2); + assert!(nd2 == nd); + + let id = IsDebug; + assert!(id == nd); + assert!(nd == id); + } + + // Don't lint: in const context + const { + assert!(5 == 2 + 3); + } + + // Don't lint: in external macro + { + // NOTE: this only works because `root_macro_call_first_node` returns `external!`, + // which then gets rejected by the macro name check + proc_macros::external!(assert!('a' == 'b')); + proc_macros::external!({ + let some_padding_before = 'a'; + assert!('a' == 'b'); + let some_padding_after = 'b'; + }); + + // .. which also means that the following is _technically_ a FN -- but surely no one would write + // code like this (diverging/unit expression as a child expression of a macro call) + vec![(), assert!('a' == 'b'), ()]; + } +} + +// Don't lint: in const context +const _: () = { + assert!(8 == (7 + 1)); +}; diff --git a/tests/ui/manual_assert_eq.stderr b/tests/ui/manual_assert_eq.stderr new file mode 100644 index 000000000000..0694df01a8f8 --- /dev/null +++ b/tests/ui/manual_assert_eq.stderr @@ -0,0 +1,88 @@ +error: used `assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:8:5 + | +LL | assert!(a == "a".to_ascii_lowercase()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-assert-eq` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_assert_eq)]` +help: replace it with `assert_eq!(..)` + | +LL - assert!(a == "a".to_ascii_lowercase()); +LL + assert_eq!(a, "a".to_ascii_lowercase()); + | + +error: used `assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:10:5 + | +LL | assert!(a != "a".to_ascii_uppercase()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert_ne!(..)` + | +LL - assert!(a != "a".to_ascii_uppercase()); +LL + assert_ne!(a, "a".to_ascii_uppercase()); + | + +error: used `debug_assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:12:5 + | +LL | debug_assert!(a == "a".to_ascii_lowercase()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert_eq!(..)` + | +LL - debug_assert!(a == "a".to_ascii_lowercase()); +LL + debug_assert_eq!(a, "a".to_ascii_lowercase()); + | + +error: used `debug_assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:14:5 + | +LL | debug_assert!(a != "a".to_ascii_uppercase()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert_ne!(..)` + | +LL - debug_assert!(a != "a".to_ascii_uppercase()); +LL + debug_assert_ne!(a, "a".to_ascii_uppercase()); + | + +error: used `assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:19:5 + | +LL | assert!(v == vec![1, 2, 3]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert_eq!(..)` + | +LL - assert!(v == vec![1, 2, 3]); +LL + assert_eq!(v, vec![1, 2, 3]); + | + +error: used `assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:21:5 + | +LL | assert!(vec![1, 2, 3] == v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert_eq!(..)` + | +LL - assert!(vec![1, 2, 3] == v); +LL + assert_eq!(vec![1, 2, 3], v); + | + +error: used `assert!` with an equality comparison + --> tests/ui/manual_assert_eq.rs:23:5 + | +LL | assert!(vec![1] == vec![1, 2, 3]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert_eq!(..)` + | +LL - assert!(vec![1] == vec![1, 2, 3]); +LL + assert_eq!(vec![1], vec![1, 2, 3]); + | + +error: aborting due to 7 previous errors + diff --git a/tests/ui/missing_asserts_for_indexing.fixed b/tests/ui/missing_asserts_for_indexing.fixed index 50bc576dd1e2..f877cbc1f114 100644 --- a/tests/ui/missing_asserts_for_indexing.fixed +++ b/tests/ui/missing_asserts_for_indexing.fixed @@ -1,4 +1,4 @@ -#![allow(unused)] +#![expect(clippy::manual_assert_eq)] #![warn(clippy::missing_asserts_for_indexing)] // ok diff --git a/tests/ui/missing_asserts_for_indexing.rs b/tests/ui/missing_asserts_for_indexing.rs index 9e219a2af073..8084e0b71be9 100644 --- a/tests/ui/missing_asserts_for_indexing.rs +++ b/tests/ui/missing_asserts_for_indexing.rs @@ -1,4 +1,4 @@ -#![allow(unused)] +#![expect(clippy::manual_assert_eq)] #![warn(clippy::missing_asserts_for_indexing)] // ok diff --git a/tests/ui/panic_in_result_fn_assertions.rs b/tests/ui/panic_in_result_fn_assertions.rs index 4e7028241579..17b221044b1f 100644 --- a/tests/ui/panic_in_result_fn_assertions.rs +++ b/tests/ui/panic_in_result_fn_assertions.rs @@ -7,7 +7,7 @@ impl A { fn result_with_assert_with_message(x: i32) -> Result // should emit lint //~^ panic_in_result_fn { - assert!(x == 5, "wrong argument"); + assert!(x.is_positive(), "wrong argument"); Ok(true) } @@ -27,7 +27,7 @@ fn result_with_assert_ne(x: i32) -> Result // should emit lint fn other_with_assert_with_message(x: i32) // should not emit lint { - assert!(x == 5, "wrong argument"); + assert!(x.is_positive(), "wrong argument"); } fn other_with_assert_eq(x: i32) // should not emit lint diff --git a/tests/ui/panic_in_result_fn_assertions.stderr b/tests/ui/panic_in_result_fn_assertions.stderr index cdb7762510d9..db881da06ba8 100644 --- a/tests/ui/panic_in_result_fn_assertions.stderr +++ b/tests/ui/panic_in_result_fn_assertions.stderr @@ -4,7 +4,7 @@ error: used `panic!()` or assertion in a function that returns `Result` LL | / fn result_with_assert_with_message(x: i32) -> Result // should emit lint LL | | LL | | { -LL | | assert!(x == 5, "wrong argument"); +LL | | assert!(x.is_positive(), "wrong argument"); LL | | Ok(true) LL | | } | |_____^ @@ -13,8 +13,8 @@ LL | | } note: return Err() instead of panicking --> tests/ui/panic_in_result_fn_assertions.rs:10:9 | -LL | assert!(x == 5, "wrong argument"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | assert!(x.is_positive(), "wrong argument"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]` diff --git a/tests/ui/panic_in_result_fn_debug_assertions.rs b/tests/ui/panic_in_result_fn_debug_assertions.rs index c4549c6b8412..9cce339f4d60 100644 --- a/tests/ui/panic_in_result_fn_debug_assertions.rs +++ b/tests/ui/panic_in_result_fn_debug_assertions.rs @@ -9,7 +9,7 @@ impl A { fn result_with_debug_assert_with_message(x: i32) -> Result { - debug_assert!(x == 5, "wrong argument"); + debug_assert!(x.is_positive(), "wrong argument"); Ok(true) } @@ -24,7 +24,7 @@ fn result_with_debug_assert_ne(x: i32) -> Result { } fn other_with_debug_assert_with_message(x: i32) { - debug_assert!(x == 5, "wrong argument"); + debug_assert!(x.is_positive(), "wrong argument"); } fn other_with_debug_assert_eq(x: i32) { diff --git a/tests/ui/uninit_vec.rs b/tests/ui/uninit_vec.rs index eeb281322da9..a0bac28e8729 100644 --- a/tests/ui/uninit_vec.rs +++ b/tests/ui/uninit_vec.rs @@ -87,7 +87,7 @@ fn main() { unsafe { // test the case where there are other statements in the following unsafe block vec.set_len(200); - assert!(vec.len() == 200); + assert_eq!(vec.len(), 200); } // handle vec stored in the field of a struct diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed index 52c114339292..b1f991b9b26c 100644 --- a/tests/ui/unnecessary_map_or.fixed +++ b/tests/ui/unnecessary_map_or.fixed @@ -1,9 +1,12 @@ //@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)] +#![allow( + clippy::no_effect, + clippy::eq_op, + clippy::unnecessary_lazy_evaluations, + clippy::nonminimal_bool, + clippy::manual_assert_eq +)] #[clippy::msrv = "1.70.0"] #[macro_use] extern crate proc_macros; diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs index dd2e1a569469..edd5ea9d878f 100644 --- a/tests/ui/unnecessary_map_or.rs +++ b/tests/ui/unnecessary_map_or.rs @@ -1,9 +1,12 @@ //@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)] +#![allow( + clippy::no_effect, + clippy::eq_op, + clippy::unnecessary_lazy_evaluations, + clippy::nonminimal_bool, + clippy::manual_assert_eq +)] #[clippy::msrv = "1.70.0"] #[macro_use] extern crate proc_macros; diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr index d11e7179f921..12a973c84213 100644 --- a/tests/ui/unnecessary_map_or.stderr +++ b/tests/ui/unnecessary_map_or.stderr @@ -1,5 +1,5 @@ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:13:13 + --> tests/ui/unnecessary_map_or.rs:16:13 | LL | let _ = Some(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _ = Some(5) == Some(5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:15:13 + --> tests/ui/unnecessary_map_or.rs:18:13 | LL | let _ = Some(5).map_or(true, |n| n != 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _ = Some(5) != Some(5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:17:13 + --> tests/ui/unnecessary_map_or.rs:20:13 | LL | let _ = Some(5).map_or(false, |n| { | _____________^ @@ -46,7 +46,7 @@ LL + let _ = Some(5) == Some(5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:22:13 + --> tests/ui/unnecessary_map_or.rs:25:13 | LL | let _ = Some(5).map_or(false, |n| { | _____________^ @@ -63,7 +63,7 @@ LL + let _ = Some(5).is_some_and(|n| { | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:27:13 + --> tests/ui/unnecessary_map_or.rs:30:13 | LL | let _ = Some(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL + let _ = Some(vec![5]).is_some_and(|n| n == [5]); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:29:13 + --> tests/ui/unnecessary_map_or.rs:32:13 | LL | let _ = Some(vec![1]).map_or(false, |n| vec![2] == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL + let _ = Some(vec![1]).is_some_and(|n| vec![2] == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:31:13 + --> tests/ui/unnecessary_map_or.rs:34:13 | LL | let _ = Some(5).map_or(false, |n| n == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL + let _ = Some(5).is_some_and(|n| n == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:33:13 + --> tests/ui/unnecessary_map_or.rs:36:13 | LL | let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL + let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 }); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:35:13 + --> tests/ui/unnecessary_map_or.rs:38:13 | LL | let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL + let _ = Ok::, i32>(vec![5]).is_ok_and(|n| n == [5]); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:37:13 + --> tests/ui/unnecessary_map_or.rs:40:13 | LL | let _ = Ok::(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL + let _ = Ok::(5) == Ok(5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:39:13 + --> tests/ui/unnecessary_map_or.rs:42:13 | LL | let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL + let _ = (Some(5) == Some(5)).then(|| 1); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:41:13 + --> tests/ui/unnecessary_map_or.rs:44:13 | LL | let _ = Some(5).map_or(true, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,7 +159,7 @@ LL + let _ = Some(5).is_none_or(|n| n == 5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:43:13 + --> tests/ui/unnecessary_map_or.rs:46:13 | LL | let _ = Some(5).map_or(true, |n| 5 == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL + let _ = Some(5).is_none_or(|n| 5 == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:45:14 + --> tests/ui/unnecessary_map_or.rs:48:14 | LL | let _ = !Some(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL + let _ = !(Some(5) == Some(5)); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:47:13 + --> tests/ui/unnecessary_map_or.rs:50:13 | LL | let _ = Some(5).map_or(false, |n| n == 5) || false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -195,7 +195,7 @@ LL + let _ = (Some(5) == Some(5)) || false; | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:49:13 + --> tests/ui/unnecessary_map_or.rs:52:13 | LL | let _ = Some(5).map_or(false, |n| n == 5) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let _ = (Some(5) == Some(5)) as usize; | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:74:13 + --> tests/ui/unnecessary_map_or.rs:77:13 | LL | let _ = r.map_or(false, |x| x == 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL + let _ = r.is_ok_and(|x| x == 7); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:80:13 + --> tests/ui/unnecessary_map_or.rs:83:13 | LL | let _ = r.map_or(false, func); | ^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL + let _ = r.is_ok_and(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:82:13 + --> tests/ui/unnecessary_map_or.rs:85:13 | LL | let _ = Some(5).map_or(false, func); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -243,7 +243,7 @@ LL + let _ = Some(5).is_some_and(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:84:13 + --> tests/ui/unnecessary_map_or.rs:87:13 | LL | let _ = Some(5).map_or(true, func); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + let _ = Some(5).is_none_or(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:90:13 + --> tests/ui/unnecessary_map_or.rs:93:13 | LL | let _ = r.map_or(false, |x| x == 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -267,7 +267,7 @@ LL + let _ = r == Ok(8); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:111:5 + --> tests/ui/unnecessary_map_or.rs:114:5 | LL | o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL + o.is_none_or(|n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:111:34 + --> tests/ui/unnecessary_map_or.rs:114:34 | LL | o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ LL + o.map_or(true, |n| n > 5) || (o as &Option).is_none_or(|n| n < 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:126:5 + --> tests/ui/unnecessary_map_or.rs:129:5 | LL | o.map_or(true, |n| n > 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -303,7 +303,7 @@ LL + o.is_none_or(|n| n > 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:131:13 + --> tests/ui/unnecessary_map_or.rs:134:13 | LL | let x = a.map_or(false, |a| a == *s); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -315,7 +315,7 @@ LL + let x = a.is_some_and(|a| a == *s); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:133:13 + --> tests/ui/unnecessary_map_or.rs:136:13 | LL | let y = b.map_or(true, |b| b == *s); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ LL + let y = b.is_none_or(|b| b == *s); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:139:13 + --> tests/ui/unnecessary_map_or.rs:142:13 | LL | assert!(Some("test").map_or(false, |x| x == "test")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -339,7 +339,7 @@ LL + assert!(Some("test") == Some("test")); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:143:13 + --> tests/ui/unnecessary_map_or.rs:146:13 | LL | assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -351,7 +351,7 @@ LL + assert!((Some("test") == Some("test")).then(|| 1).is_some()); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:160:9 + --> tests/ui/unnecessary_map_or.rs:163:9 | LL | _ = s.lock().unwrap().map_or(false, |s| s == "foo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -363,7 +363,7 @@ LL + _ = s.lock().unwrap().is_some_and(|s| s == "foo"); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:164:9 + --> tests/ui/unnecessary_map_or.rs:167:9 | LL | _ = s.map_or(false, |s| s == "foo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^