From e341245ba8870e9416b803d2cce1655493e0b59d Mon Sep 17 00:00:00 2001 From: ceptontech <> Date: Thu, 30 Oct 2025 16:18:22 -0700 Subject: [PATCH 1/3] refactor(search_is_some): Move some logic for transforming closures The lint `search_is_some` involves converting a closure that takes the reference into one that takes the value. The code is split between the function for the lint and a shared function. The new feature that we are adding involves the same transformation. To do so it needs some of the same code that is currently in the `search_is_some` lint. So it is moved from the lint into the shared function. Before this patch, line 799 in the file `clippy_utils/src/sugg.rs` had a check. It made the function return none in case the closure did not dereference the argument. However, the code for the lint `search_is_some` would then fall back to using the original closure. That achieved the same effect as the check not existing. So the check is now removed. --- clippy_lints/src/methods/search_is_some.rs | 26 +++++-------------- clippy_utils/src/sugg.rs | 30 +++++++++++++++------- clippy_utils/src/sym.rs | 1 + 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index 8732eba6d4e8..956e676e9704 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -2,11 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::deref_closure_args; -use clippy_utils::{is_receiver_of_method_call, strip_pat_refs, sym}; -use hir::ExprKind; +use clippy_utils::{is_receiver_of_method_call, sym}; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::PatKind; use rustc_lint::LateContext; use rustc_span::{Span, Symbol}; @@ -34,25 +32,15 @@ pub(super) fn check<'tcx>( { let msg = format!("called `{option_check_method}()` after searching an `Iterator` with `{search_method}`"); let search_snippet = snippet(cx, search_arg.span, ".."); + // `find()` provides a reference to the item, but `any` does not, so we + // should fix item usages for suggestion // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` let mut applicability = Applicability::MachineApplicable; - let any_search_snippet = if search_method == sym::find - && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind - && let closure_body = cx.tcx.hir_body(body) - && let Some(closure_arg) = closure_body.params.first() - { - if let PatKind::Ref(..) = closure_arg.pat.kind { - Some(search_snippet.replacen('&', "", 1)) - } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind { - // `find()` provides a reference to the item, but `any` does not, - // so we should fix item usages for suggestion - if let Some(closure_sugg) = deref_closure_args(cx, search_arg) { - applicability = closure_sugg.applicability; - Some(closure_sugg.suggestion) - } else { - Some(search_snippet.to_string()) - } + let any_search_snippet = if search_method == sym::find { + if let Some(closure_sugg) = deref_closure_args(cx, search_arg) { + applicability = closure_sugg.applicability; + Some(closure_sugg.suggestion) } else { None } diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 2593df103527..30d073e74573 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -3,12 +3,12 @@ use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context}; use crate::ty::expr_sig; -use crate::{get_parent_expr_for_hir, higher}; +use crate::{get_parent_expr_for_hir, higher, strip_pat_refs}; use rustc_ast::util::parser::AssocOp; use rustc_ast::{UnOp, ast}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::{self as hir, Closure, ExprKind, HirId, MutTy, Node, TyKind}; +use rustc_hir::{self as hir, Closure, ExprKind, HirId, MutTy, Node, PatKind, TyKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; @@ -774,8 +774,22 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti if let ExprKind::Closure(&Closure { fn_decl, def_id, body, .. }) = closure.kind + && let closure_body = cx.tcx.hir_body(body) + && let [closure_arg] = closure_body.params { - let closure_body = cx.tcx.hir_body(body); + // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` + if matches!(closure_arg.pat.kind, PatKind::Ref(..)) { + let mut applicability = Applicability::MachineApplicable; + let suggestion = + snippet_with_applicability(cx, closure.span, "..", &mut applicability).replacen('&', "", 1); + return Some(DerefClosure { + applicability, + suggestion, + }); + } + if !matches!(strip_pat_refs(closure_arg.pat).kind, PatKind::Binding(..)) { + return None; + } // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`) // a type annotation is present if param `kind` is different from `TyKind::Infer` let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind @@ -800,12 +814,10 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti .consume_body(closure_body) .into_ok(); - if !visitor.suggestion_start.is_empty() { - return Some(DerefClosure { - applicability: visitor.applicability, - suggestion: visitor.finish(), - }); - } + return Some(DerefClosure { + applicability: visitor.applicability, + suggestion: visitor.finish(), + }); } None } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 8e8a80a6a9c9..51942e3471d9 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -198,6 +198,7 @@ generate! { is_none, is_none_or, is_ok, + is_ok_and, is_partitioned, is_some, is_some_and, From 9cf8ea832544814418f2382c39b340c8cedd1263 Mon Sep 17 00:00:00 2001 From: ceptontech <> Date: Mon, 3 Nov 2025 09:02:50 -0800 Subject: [PATCH 2/3] feat(manual_is_variant): Check for `.iter().any()` Now the linter checks for calling the `iter` or `into_iter` method followed by calling the `all` or `any` method. We have used these methods by mistake ourselves. The developer was not familiar with the `is_some_and` method. He tried to use the `any` method on an option. The compiler suggested using `iter` first. The developer did not get to learn about the idiomatic method. changelog: [`manual_is_variant`]: check for calling the `iter` or `into_iter` method followed by calling the `all` or `any` method --- .../src/methods/manual_is_variant_and.rs | 86 ++++- clippy_lints/src/methods/mod.rs | 12 +- tests/ui/manual_is_variant_and.fixed | 94 ++++- tests/ui/manual_is_variant_and.rs | 94 ++++- tests/ui/manual_is_variant_and.stderr | 351 ++++++++++++++++-- 5 files changed, 595 insertions(+), 42 deletions(-) diff --git a/clippy_lints/src/methods/manual_is_variant_and.rs b/clippy_lints/src/methods/manual_is_variant_and.rs index 8f65858987b9..b79a9b66230e 100644 --- a/clippy_lints/src/methods/manual_is_variant_and.rs +++ b/clippy_lints/src/methods/manual_is_variant_and.rs @@ -1,8 +1,9 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; use clippy_utils::source::{snippet, snippet_with_applicability}; -use clippy_utils::sugg::Sugg; +use clippy_utils::sugg::{DerefClosure, Sugg, deref_closure_args}; +use clippy_utils::ty::is_copy; use clippy_utils::{get_parent_expr, sym}; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -12,9 +13,9 @@ use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::{Span, Symbol}; -use super::MANUAL_IS_VARIANT_AND; +use super::{MANUAL_IS_VARIANT_AND, method_call}; -pub(super) fn check( +pub(super) fn check_map_unwrap_or_default( cx: &LateContext<'_>, expr: &Expr<'_>, map_recv: &Expr<'_>, @@ -217,3 +218,80 @@ pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) { } } } + +/// Check for things like `.into_iter().all()`. +pub(super) fn check_iter_reduce( + cx: &LateContext<'_>, + expr: &Expr<'_>, + recv: &Expr<'_>, + arg: &Expr<'_>, + second_call: Span, + msrv: Msrv, + method: Symbol, +) { + // Find how the iterator is created. + let (mut referenced, first_recv, first_call) = match method_call(recv) { + Some((sym::into_iter, first_recv, [], _, first_call)) => (false, first_recv, first_call), + Some((sym::iter, first_recv, [], _, first_call)) => (true, first_recv, first_call), + _ => { + return; + }, + }; + + // Find the method to suggest. + let recv_type = cx.typeck_results().expr_ty(first_recv); + let (replacement_method, since_version) = match recv_type.kind() { + ty::Adt(adt, _) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) && method == sym::any => { + (sym::is_ok_and, msrvs::OPTION_RESULT_IS_VARIANT_AND) + }, + ty::Adt(adt, _) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) => match method { + sym::all => (sym::is_none_or, msrvs::IS_NONE_OR), + sym::any => (sym::is_some_and, msrvs::OPTION_RESULT_IS_VARIANT_AND), + _ => panic!("The method is checked in the caller."), + }, + _ => return, + }; + if !msrv.meets(cx, since_version) { + return; + } + + // The replacement methods pass the value to the closure. The original + // methods may pass the reference. If possible, the program modifies the + // closure to take the value. + let (replacement_closure, applicability) = if referenced + && is_copy(cx, recv_type) + && let Some(DerefClosure { + suggestion, + applicability, + }) = deref_closure_args(cx, arg) + { + referenced = false; + (Some((arg.span, suggestion)), applicability) + } else { + (None, Applicability::MachineApplicable) + }; + // If it is not possible to modify the closure, the program suggests the + // `as_ref` method. + let replacement_call = if referenced { + format!("as_ref().{replacement_method}") + } else { + replacement_method.to_string() + }; + + let mut suggestion = vec![ + // Remove the call to get the iterator. + (first_call.with_lo(first_recv.span.hi()), String::new()), + // Replace the call to reduce it. + (second_call, replacement_call), + ]; + suggestion.extend(replacement_closure); + span_lint_and_then( + cx, + MANUAL_IS_VARIANT_AND, + expr.span, + format!("use of `option::Iter::{method}`"), + |diag| { + diag.multipart_suggestion(format!("use `{replacement_method}` instead"), suggestion, applicability); + }, + ); +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5b917e2bfefa..a4a16d746df4 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3915,6 +3915,10 @@ declare_clippy_lint! { /// result.map(|a| a > 10) == Ok(true); /// option.map(|a| a > 10) != Some(true); /// result.map(|a| a > 10) != Ok(true); + /// + /// option.into_iter().any(|a| a > 10); + /// result.into_iter().any(|a| a > 10); + /// option.into_iter().all(|a| a > 10); /// ``` /// Use instead: /// ```no_run @@ -3927,6 +3931,10 @@ declare_clippy_lint! { /// result.is_ok_and(|a| a > 10); /// option.is_none_or(|a| a > 10); /// !result.is_ok_and(|a| a > 10); + /// + /// option.is_some_and(|a| a > 10); + /// result.is_ok_and(|a| a > 10); + /// option.is_none_or(|a| a > 10); /// ``` #[clippy::version = "1.77.0"] pub MANUAL_IS_VARIANT_AND, @@ -5025,6 +5033,7 @@ impl Methods { zst_offset::check(cx, expr, recv); }, (sym::all, [arg]) => { + manual_is_variant_and::check_iter_reduce(cx, expr, recv, arg, span, self.msrv, name); needless_character_iteration::check(cx, expr, recv, arg, true); match method_call(recv) { Some((sym::cloned, recv2, [], _, _)) => { @@ -5054,6 +5063,7 @@ impl Methods { } }, (sym::any, [arg]) => { + manual_is_variant_and::check_iter_reduce(cx, expr, recv, arg, span, self.msrv, name); needless_character_iteration::check(cx, expr, recv, arg, false); match method_call(recv) { Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( @@ -5596,7 +5606,7 @@ impl Methods { (sym::unwrap_or_default, []) => { match method_call(recv) { Some((sym::map, m_recv, [arg], span, _)) => { - manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv); + manual_is_variant_and::check_map_unwrap_or_default(cx, expr, m_recv, arg, span, self.msrv); }, Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check( diff --git a/tests/ui/manual_is_variant_and.fixed b/tests/ui/manual_is_variant_and.fixed index 65a9cfa6e64c..9423c574b722 100644 --- a/tests/ui/manual_is_variant_and.fixed +++ b/tests/ui/manual_is_variant_and.fixed @@ -27,6 +27,12 @@ macro_rules! some_false { }; } +macro_rules! into_iter { + ($x:expr) => { + $x.into_iter() + }; +} + macro_rules! mac { (some $e:expr) => { Some($e) @@ -42,8 +48,51 @@ macro_rules! mac { }; } +#[clippy::msrv = "1.69"] +fn under_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.into_iter().any(|x| x != 0); + let _ = opt.map(|x| x != 0).unwrap_or_default(); + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.iter().any(|&x| x != 0); +} + +#[clippy::msrv = "1.70"] +fn meets_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and +} + +#[clippy::msrv = "1.81"] +fn under_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and +} + +#[clippy::msrv = "1.82"] +fn meets_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_none_or(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and +} + #[rustfmt::skip] fn option_methods() { + let opt_non_copy: Option = None; let opt = Some(1); // Check for `option.map(_).unwrap_or_default()` use. @@ -67,6 +116,36 @@ fn option_methods() { //~^ manual_is_variant_and let _ = Some(2).is_none_or(|x| x % 2 == 0); //~^ manual_is_variant_and + let _ = opt.is_none_or(|x| x != 0); + //~^ manual_is_variant_and + let _ = (opt).is_none_or(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_some_and(i32::is_negative); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and + + // The type does not copy. The linter should suggest `as_ref`. + let _ = (opt_non_copy).as_ref().is_some_and(|x| x.is_empty()); + //~^ manual_is_variant_and + let _ = opt_non_copy.as_ref().is_some_and(|x| x.is_empty()); + //~^ manual_is_variant_and + let _ = opt_non_copy.as_ref().is_some_and(|x| ".." == *x); + //~^ manual_is_variant_and + // The type copies. The linter should not suggest `as_ref`. + let _ = opt.is_none_or(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.as_ref().is_none_or(|_| false); + //~^ manual_is_variant_and + let _ = opt.is_some_and(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.is_none_or(|_| false); + //~^ manual_is_variant_and + // The argument is defined elsewhere. It cannot be changed to take the + // value. The linter should suggest `as_ref`. + let zerop = |x: &i32| *x == 0; + let _ = opt.as_ref().is_none_or(zerop); + //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = opt.map(|x| x + 1).unwrap_or_default(); @@ -83,10 +162,13 @@ fn option_methods() { let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true); let _ = mac!(some_map 2) == Some(true); let _ = mac!(map Some(2)) == Some(true); + // The first method call is elsewhere. The linter cannot change it. + let _ = into_iter!(opt).any(|x| x != 0); } #[rustfmt::skip] fn result_methods() { + let res_non_copy: Result = Ok(1); let res: Result = Ok(1); // multi line cases @@ -102,6 +184,12 @@ fn result_methods() { //~^ manual_is_variant_and let _ = !Ok::(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and + let _ = res.is_ok_and(i32::is_negative); + //~^ manual_is_variant_and + let _ = res_non_copy.as_ref().is_ok_and(|x| *x != 0); + //~^ manual_is_variant_and + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = res.map(|x| x + 1).unwrap_or_default(); @@ -109,7 +197,11 @@ fn result_methods() { let res2: Result = Ok('a'); let _ = res2.is_ok_and(char::is_alphanumeric); // should lint //~^ manual_is_variant_and - let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint + + // should not lint + let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); + // The result type comes with no shorthand for all. + let _ = res.into_iter().all(i32::is_negative); } fn main() { diff --git a/tests/ui/manual_is_variant_and.rs b/tests/ui/manual_is_variant_and.rs index 85b45d654a7d..4146a6c73f35 100644 --- a/tests/ui/manual_is_variant_and.rs +++ b/tests/ui/manual_is_variant_and.rs @@ -27,6 +27,12 @@ macro_rules! some_false { }; } +macro_rules! into_iter { + ($x:expr) => { + $x.into_iter() + }; +} + macro_rules! mac { (some $e:expr) => { Some($e) @@ -42,8 +48,51 @@ macro_rules! mac { }; } +#[clippy::msrv = "1.69"] +fn under_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.into_iter().any(|x| x != 0); + let _ = opt.map(|x| x != 0).unwrap_or_default(); + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.iter().any(|&x| x != 0); +} + +#[clippy::msrv = "1.70"] +fn meets_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.into_iter().any(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.map(|x| x != 0).unwrap_or_default(); + //~^ manual_is_variant_and + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.iter().any(|&x| x != 0); + //~^ manual_is_variant_and +} + +#[clippy::msrv = "1.81"] +fn under_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.into_iter().any(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.map(|x| x != 0).unwrap_or_default(); + //~^ manual_is_variant_and + let _ = opt.iter().all(|x| *x != 0); + let _ = opt.iter().any(|&x| x != 0); + //~^ manual_is_variant_and +} + +#[clippy::msrv = "1.82"] +fn meets_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.into_iter().any(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.map(|x| x != 0).unwrap_or_default(); + //~^ manual_is_variant_and + let _ = opt.iter().all(|x| *x != 0); + //~^ manual_is_variant_and + let _ = opt.iter().any(|&x| x != 0); + //~^ manual_is_variant_and +} + #[rustfmt::skip] fn option_methods() { + let opt_non_copy: Option = None; let opt = Some(1); // Check for `option.map(_).unwrap_or_default()` use. @@ -73,6 +122,36 @@ fn option_methods() { //~^ manual_is_variant_and let _ = Some(2).map(|x| x % 2 == 0) != some_false!(); //~^ manual_is_variant_and + let _ = opt.into_iter().all(|x| x != 0); + //~^ manual_is_variant_and + let _ = (opt.into_iter()).all(|x| x != 0); + //~^ manual_is_variant_and + let _ = opt.into_iter().any(i32::is_negative); + //~^ manual_is_variant_and + let _ = opt.into_iter().any(|x| x != 0); + //~^ manual_is_variant_and + + // The type does not copy. The linter should suggest `as_ref`. + let _ = (opt_non_copy.iter()).any(|x| x.is_empty()); + //~^ manual_is_variant_and + let _ = opt_non_copy.iter().any(|x| x.is_empty()); + //~^ manual_is_variant_and + let _ = opt_non_copy.iter().any(|x| ".." == *x); + //~^ manual_is_variant_and + // The type copies. The linter should not suggest `as_ref`. + let _ = opt.iter().all(|x| *x != 0); + //~^ manual_is_variant_and + let _ = opt.iter().all(|_| false); + //~^ manual_is_variant_and + let _ = opt.iter().any(|&x| x != 0); + //~^ manual_is_variant_and + let _ = opt.iter().all(|&_| false); + //~^ manual_is_variant_and + // The argument is defined elsewhere. It cannot be changed to take the + // value. The linter should suggest `as_ref`. + let zerop = |x: &i32| *x == 0; + let _ = opt.iter().all(zerop); + //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = opt.map(|x| x + 1).unwrap_or_default(); @@ -89,10 +168,13 @@ fn option_methods() { let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true); let _ = mac!(some_map 2) == Some(true); let _ = mac!(map Some(2)) == Some(true); + // The first method call is elsewhere. The linter cannot change it. + let _ = into_iter!(opt).any(|x| x != 0); } #[rustfmt::skip] fn result_methods() { + let res_non_copy: Result = Ok(1); let res: Result = Ok(1); // multi line cases @@ -111,6 +193,12 @@ fn result_methods() { //~^ manual_is_variant_and let _ = Ok::(2).map(|x| x.is_multiple_of(2)) != Ok(true); //~^ manual_is_variant_and + let _ = res.into_iter().any(i32::is_negative); + //~^ manual_is_variant_and + let _ = res_non_copy.iter().any(|x| *x != 0); + //~^ manual_is_variant_and + let _ = res.iter().any(|x| *x != 0); + //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` let _ = res.map(|x| x + 1).unwrap_or_default(); @@ -118,7 +206,11 @@ fn result_methods() { let res2: Result = Ok('a'); let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint //~^ manual_is_variant_and - let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint + + // should not lint + let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); + // The result type comes with no shorthand for all. + let _ = res.into_iter().all(i32::is_negative); } fn main() { diff --git a/tests/ui/manual_is_variant_and.stderr b/tests/ui/manual_is_variant_and.stderr index da36b5a07d21..5974c04d6339 100644 --- a/tests/ui/manual_is_variant_and.stderr +++ b/tests/ui/manual_is_variant_and.stderr @@ -1,17 +1,118 @@ +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:61:13 + | +LL | let _ = res.into_iter().any(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-is-variant-and` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]` +help: use `is_ok_and` instead + | +LL - let _ = res.into_iter().any(|x| x != 0); +LL + let _ = res.is_ok_and(|x| x != 0); + | + +error: called `map().unwrap_or_default()` on an `Option` value + --> tests/ui/manual_is_variant_and.rs:63:17 + | +LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:66:13 + | +LL | let _ = opt.iter().any(|&x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.iter().any(|&x| x != 0); +LL + let _ = opt.is_some_and(|x| x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:72:13 + | +LL | let _ = res.into_iter().any(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and` instead + | +LL - let _ = res.into_iter().any(|x| x != 0); +LL + let _ = res.is_ok_and(|x| x != 0); + | + error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:51:17 + --> tests/ui/manual_is_variant_and.rs:74:17 + | +LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:77:13 + | +LL | let _ = opt.iter().any(|&x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.iter().any(|&x| x != 0); +LL + let _ = opt.is_some_and(|x| x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:83:13 + | +LL | let _ = res.into_iter().any(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and` instead + | +LL - let _ = res.into_iter().any(|x| x != 0); +LL + let _ = res.is_ok_and(|x| x != 0); + | + +error: called `map().unwrap_or_default()` on an `Option` value + --> tests/ui/manual_is_variant_and.rs:85:17 + | +LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:87:13 + | +LL | let _ = opt.iter().all(|x| *x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.iter().all(|x| *x != 0); +LL + let _ = opt.is_none_or(|x| x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:89:13 + | +LL | let _ = opt.iter().any(|&x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.iter().any(|&x| x != 0); +LL + let _ = opt.is_some_and(|x| x != 0); + | + +error: called `map().unwrap_or_default()` on an `Option` value + --> tests/ui/manual_is_variant_and.rs:100:17 | LL | let _ = opt.map(|x| x > 1) | _________________^ ... | LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` - | - = note: `-D clippy::manual-is-variant-and` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:56:17 + --> tests/ui/manual_is_variant_and.rs:105:17 | LL | let _ = opt.map(|x| { | _________________^ @@ -30,13 +131,13 @@ LL ~ }); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:61:17 + --> tests/ui/manual_is_variant_and.rs:110:17 | LL | let _ = opt.map(|x| x > 1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x > 1)` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:64:10 + --> tests/ui/manual_is_variant_and.rs:113:10 | LL | .map(|x| x > 1) | __________^ @@ -45,37 +146,181 @@ LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:68:13 + --> tests/ui/manual_is_variant_and.rs:117:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:70:13 + --> tests/ui/manual_is_variant_and.rs:119:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 != 0)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:72:13 + --> tests/ui/manual_is_variant_and.rs:121:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) == some_true!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:74:13 + --> tests/ui/manual_is_variant_and.rs:123:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) != some_false!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 == 0)` +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:125:13 + | +LL | let _ = opt.into_iter().all(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.into_iter().all(|x| x != 0); +LL + let _ = opt.is_none_or(|x| x != 0); + | + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:127:13 + | +LL | let _ = (opt.into_iter()).all(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = (opt.into_iter()).all(|x| x != 0); +LL + let _ = (opt).is_none_or(|x| x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:129:13 + | +LL | let _ = opt.into_iter().any(i32::is_negative); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.into_iter().any(i32::is_negative); +LL + let _ = opt.is_some_and(i32::is_negative); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:131:13 + | +LL | let _ = opt.into_iter().any(|x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.into_iter().any(|x| x != 0); +LL + let _ = opt.is_some_and(|x| x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:135:13 + | +LL | let _ = (opt_non_copy.iter()).any(|x| x.is_empty()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = (opt_non_copy.iter()).any(|x| x.is_empty()); +LL + let _ = (opt_non_copy).as_ref().is_some_and(|x| x.is_empty()); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:137:13 + | +LL | let _ = opt_non_copy.iter().any(|x| x.is_empty()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt_non_copy.iter().any(|x| x.is_empty()); +LL + let _ = opt_non_copy.as_ref().is_some_and(|x| x.is_empty()); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:139:13 + | +LL | let _ = opt_non_copy.iter().any(|x| ".." == *x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt_non_copy.iter().any(|x| ".." == *x); +LL + let _ = opt_non_copy.as_ref().is_some_and(|x| ".." == *x); + | + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:142:13 + | +LL | let _ = opt.iter().all(|x| *x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.iter().all(|x| *x != 0); +LL + let _ = opt.is_none_or(|x| x != 0); + | + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:144:13 + | +LL | let _ = opt.iter().all(|_| false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.iter().all(|_| false); +LL + let _ = opt.as_ref().is_none_or(|_| false); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:146:13 + | +LL | let _ = opt.iter().any(|&x| x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and` instead + | +LL - let _ = opt.iter().any(|&x| x != 0); +LL + let _ = opt.is_some_and(|x| x != 0); + | + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:148:13 + | +LL | let _ = opt.iter().all(|&_| false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.iter().all(|&_| false); +LL + let _ = opt.is_none_or(|_| false); + | + +error: use of `option::Iter::all` + --> tests/ui/manual_is_variant_and.rs:153:13 + | +LL | let _ = opt.iter().all(zerop); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_none_or` instead + | +LL - let _ = opt.iter().all(zerop); +LL + let _ = opt.as_ref().is_none_or(zerop); + | + error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:81:18 + --> tests/ui/manual_is_variant_and.rs:160:18 | LL | let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(char::is_alphanumeric)` error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:99:17 + --> tests/ui/manual_is_variant_and.rs:181:17 | LL | let _ = res.map(|x| { | _________________^ @@ -94,7 +339,7 @@ LL ~ }); | error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:104:17 + --> tests/ui/manual_is_variant_and.rs:186:17 | LL | let _ = res.map(|x| x > 1) | _________________^ @@ -103,124 +348,160 @@ LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_ok_and(|x| x > 1)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:108:13 + --> tests/ui/manual_is_variant_and.rs:190:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:110:13 + --> tests/ui/manual_is_variant_and.rs:192:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:112:13 + --> tests/ui/manual_is_variant_and.rs:194:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:196:13 + | +LL | let _ = res.into_iter().any(i32::is_negative); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and` instead + | +LL - let _ = res.into_iter().any(i32::is_negative); +LL + let _ = res.is_ok_and(i32::is_negative); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:198:13 + | +LL | let _ = res_non_copy.iter().any(|x| *x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and` instead + | +LL - let _ = res_non_copy.iter().any(|x| *x != 0); +LL + let _ = res_non_copy.as_ref().is_ok_and(|x| *x != 0); + | + +error: use of `option::Iter::any` + --> tests/ui/manual_is_variant_and.rs:200:13 + | +LL | let _ = res.iter().any(|x| *x != 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and` instead + | +LL - let _ = res.iter().any(|x| *x != 0); +LL + let _ = res.is_ok_and(|x| x != 0); + | + error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:119:18 + --> tests/ui/manual_is_variant_and.rs:207:18 | LL | let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:132:18 + --> tests/ui/manual_is_variant_and.rs:224:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| !b.is_ascii_digit())` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:139:18 + --> tests/ui/manual_is_variant_and.rs:231:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:146:18 + --> tests/ui/manual_is_variant_and.rs:238:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:153:18 + --> tests/ui/manual_is_variant_and.rs:245:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| !b.is_ascii_digit())` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:161:18 + --> tests/ui/manual_is_variant_and.rs:253:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| b.is_ascii_digit())` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:168:18 + --> tests/ui/manual_is_variant_and.rs:260:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| !b.is_ascii_digit())` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:175:18 + --> tests/ui/manual_is_variant_and.rs:267:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| b.is_ascii_digit())` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:182:18 + --> tests/ui/manual_is_variant_and.rs:274:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| !b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:195:18 + --> tests/ui/manual_is_variant_and.rs:287:18 | LL | let a1 = b.map(iad) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(iad)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:200:18 + --> tests/ui/manual_is_variant_and.rs:292:18 | LL | let a1 = b.map(iad) == Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(|x| !iad(x))` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:205:18 + --> tests/ui/manual_is_variant_and.rs:297:18 | LL | let a1 = b.map(iad) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(|x| !iad(x))` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:210:18 + --> tests/ui/manual_is_variant_and.rs:302:18 | LL | let a1 = b.map(iad) != Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(iad)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:217:18 + --> tests/ui/manual_is_variant_and.rs:309:18 | LL | let a1 = b.map(iad) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(iad)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:222:18 + --> tests/ui/manual_is_variant_and.rs:314:18 | LL | let a1 = b.map(iad) == Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(|x| !iad(x))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:227:18 + --> tests/ui/manual_is_variant_and.rs:319:18 | LL | let a1 = b.map(iad) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(iad)` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:232:18 + --> tests/ui/manual_is_variant_and.rs:324:18 | LL | let a1 = b.map(iad) != Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(|x| !iad(x))` -error: aborting due to 31 previous errors +error: aborting due to 56 previous errors From 844c1c02479db0652c7c4b088c383e744b0f34fd Mon Sep 17 00:00:00 2001 From: ceptontech <> Date: Thu, 30 Oct 2025 16:18:22 -0700 Subject: [PATCH 3/3] fix(manual_is_variant): Skip old versions changelog: [`manual_is_variant`]: skip the check when the MSRV is before 1.70 --- .../src/methods/manual_is_variant_and.rs | 5 +- clippy_lints/src/methods/mod.rs | 2 +- tests/ui/manual_is_variant_and.fixed | 7 + tests/ui/manual_is_variant_and.rs | 7 + tests/ui/manual_is_variant_and.stderr | 137 ++++++++++-------- 5 files changed, 97 insertions(+), 61 deletions(-) diff --git a/clippy_lints/src/methods/manual_is_variant_and.rs b/clippy_lints/src/methods/manual_is_variant_and.rs index b79a9b66230e..3a9237c85a3f 100644 --- a/clippy_lints/src/methods/manual_is_variant_and.rs +++ b/clippy_lints/src/methods/manual_is_variant_and.rs @@ -190,7 +190,10 @@ fn emit_lint<'tcx>( ); } -pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) { +pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) { + if !msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) { + return; + } if let Some(parent_expr) = get_parent_expr(cx, expr) && let ExprKind::Binary(op, left, right) = parent_expr.kind && op.span.eq_ctxt(expr.span) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index a4a16d746df4..421f885aca5d 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5340,7 +5340,7 @@ impl Methods { if name == sym::map { map_clone::check(cx, expr, recv, m_arg, self.msrv); map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, self.msrv, span); - manual_is_variant_and::check_map(cx, expr); + manual_is_variant_and::check_map(cx, expr, self.msrv); match method_call(recv) { Some((map_name @ (sym::iter | sym::into_iter), recv2, _, _, _)) => { iter_kv_map::check(cx, map_name, expr, recv2, m_arg, self.msrv); diff --git a/tests/ui/manual_is_variant_and.fixed b/tests/ui/manual_is_variant_and.fixed index 9423c574b722..89c67f596795 100644 --- a/tests/ui/manual_is_variant_and.fixed +++ b/tests/ui/manual_is_variant_and.fixed @@ -50,6 +50,7 @@ macro_rules! mac { #[clippy::msrv = "1.69"] fn under_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.map(|x| x != 0) == Ok(true); let _ = res.into_iter().any(|x| x != 0); let _ = opt.map(|x| x != 0).unwrap_or_default(); let _ = opt.iter().all(|x| *x != 0); @@ -58,6 +59,8 @@ fn under_msrv_is_some_and(opt: Option, res: Result) { #[clippy::msrv = "1.70"] fn meets_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and let _ = res.is_ok_and(|x| x != 0); //~^ manual_is_variant_and let _ = opt.is_some_and(|x| x != 0); @@ -69,6 +72,8 @@ fn meets_msrv_is_some_and(opt: Option, res: Result) { #[clippy::msrv = "1.81"] fn under_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and let _ = res.is_ok_and(|x| x != 0); //~^ manual_is_variant_and let _ = opt.is_some_and(|x| x != 0); @@ -80,6 +85,8 @@ fn under_msrv_is_none_or(opt: Option, res: Result) { #[clippy::msrv = "1.82"] fn meets_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.is_ok_and(|x| x != 0); + //~^ manual_is_variant_and let _ = res.is_ok_and(|x| x != 0); //~^ manual_is_variant_and let _ = opt.is_some_and(|x| x != 0); diff --git a/tests/ui/manual_is_variant_and.rs b/tests/ui/manual_is_variant_and.rs index 4146a6c73f35..bc2000dc834f 100644 --- a/tests/ui/manual_is_variant_and.rs +++ b/tests/ui/manual_is_variant_and.rs @@ -50,6 +50,7 @@ macro_rules! mac { #[clippy::msrv = "1.69"] fn under_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.map(|x| x != 0) == Ok(true); let _ = res.into_iter().any(|x| x != 0); let _ = opt.map(|x| x != 0).unwrap_or_default(); let _ = opt.iter().all(|x| *x != 0); @@ -58,6 +59,8 @@ fn under_msrv_is_some_and(opt: Option, res: Result) { #[clippy::msrv = "1.70"] fn meets_msrv_is_some_and(opt: Option, res: Result) { + let _ = res.map(|x| x != 0) == Ok(true); + //~^ manual_is_variant_and let _ = res.into_iter().any(|x| x != 0); //~^ manual_is_variant_and let _ = opt.map(|x| x != 0).unwrap_or_default(); @@ -69,6 +72,8 @@ fn meets_msrv_is_some_and(opt: Option, res: Result) { #[clippy::msrv = "1.81"] fn under_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.map(|x| x != 0) == Ok(true); + //~^ manual_is_variant_and let _ = res.into_iter().any(|x| x != 0); //~^ manual_is_variant_and let _ = opt.map(|x| x != 0).unwrap_or_default(); @@ -80,6 +85,8 @@ fn under_msrv_is_none_or(opt: Option, res: Result) { #[clippy::msrv = "1.82"] fn meets_msrv_is_none_or(opt: Option, res: Result) { + let _ = res.map(|x| x != 0) == Ok(true); + //~^ manual_is_variant_and let _ = res.into_iter().any(|x| x != 0); //~^ manual_is_variant_and let _ = opt.map(|x| x != 0).unwrap_or_default(); diff --git a/tests/ui/manual_is_variant_and.stderr b/tests/ui/manual_is_variant_and.stderr index 5974c04d6339..1898e2266081 100644 --- a/tests/ui/manual_is_variant_and.stderr +++ b/tests/ui/manual_is_variant_and.stderr @@ -1,11 +1,18 @@ +error: called `.map() == Ok()` + --> tests/ui/manual_is_variant_and.rs:62:13 + | +LL | let _ = res.map(|x| x != 0) == Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `res.is_ok_and(|x| x != 0)` + | + = note: `-D clippy::manual-is-variant-and` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]` + error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:61:13 + --> tests/ui/manual_is_variant_and.rs:64:13 | LL | let _ = res.into_iter().any(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::manual-is-variant-and` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]` help: use `is_ok_and` instead | LL - let _ = res.into_iter().any(|x| x != 0); @@ -13,13 +20,13 @@ LL + let _ = res.is_ok_and(|x| x != 0); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:63:17 + --> tests/ui/manual_is_variant_and.rs:66:17 | LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:66:13 + --> tests/ui/manual_is_variant_and.rs:69:13 | LL | let _ = opt.iter().any(|&x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,8 +37,14 @@ LL - let _ = opt.iter().any(|&x| x != 0); LL + let _ = opt.is_some_and(|x| x != 0); | +error: called `.map() == Ok()` + --> tests/ui/manual_is_variant_and.rs:75:13 + | +LL | let _ = res.map(|x| x != 0) == Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `res.is_ok_and(|x| x != 0)` + error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:72:13 + --> tests/ui/manual_is_variant_and.rs:77:13 | LL | let _ = res.into_iter().any(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,13 +56,13 @@ LL + let _ = res.is_ok_and(|x| x != 0); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:74:17 + --> tests/ui/manual_is_variant_and.rs:79:17 | LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:77:13 + --> tests/ui/manual_is_variant_and.rs:82:13 | LL | let _ = opt.iter().any(|&x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,8 +73,14 @@ LL - let _ = opt.iter().any(|&x| x != 0); LL + let _ = opt.is_some_and(|x| x != 0); | +error: called `.map() == Ok()` + --> tests/ui/manual_is_variant_and.rs:88:13 + | +LL | let _ = res.map(|x| x != 0) == Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `res.is_ok_and(|x| x != 0)` + error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:83:13 + --> tests/ui/manual_is_variant_and.rs:90:13 | LL | let _ = res.into_iter().any(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,13 +92,13 @@ LL + let _ = res.is_ok_and(|x| x != 0); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:85:17 + --> tests/ui/manual_is_variant_and.rs:92:17 | LL | let _ = opt.map(|x| x != 0).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x != 0)` error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:87:13 + --> tests/ui/manual_is_variant_and.rs:94:13 | LL | let _ = opt.iter().all(|x| *x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -91,7 +110,7 @@ LL + let _ = opt.is_none_or(|x| x != 0); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:89:13 + --> tests/ui/manual_is_variant_and.rs:96:13 | LL | let _ = opt.iter().any(|&x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +122,7 @@ LL + let _ = opt.is_some_and(|x| x != 0); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:100:17 + --> tests/ui/manual_is_variant_and.rs:107:17 | LL | let _ = opt.map(|x| x > 1) | _________________^ @@ -112,7 +131,7 @@ LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:105:17 + --> tests/ui/manual_is_variant_and.rs:112:17 | LL | let _ = opt.map(|x| { | _________________^ @@ -131,13 +150,13 @@ LL ~ }); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:110:17 + --> tests/ui/manual_is_variant_and.rs:117:17 | LL | let _ = opt.map(|x| x > 1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x > 1)` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:113:10 + --> tests/ui/manual_is_variant_and.rs:120:10 | LL | .map(|x| x > 1) | __________^ @@ -146,31 +165,31 @@ LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:117:13 + --> tests/ui/manual_is_variant_and.rs:124:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:119:13 + --> tests/ui/manual_is_variant_and.rs:126:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 != 0)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:121:13 + --> tests/ui/manual_is_variant_and.rs:128:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) == some_true!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:123:13 + --> tests/ui/manual_is_variant_and.rs:130:13 | LL | let _ = Some(2).map(|x| x % 2 == 0) != some_false!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 == 0)` error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:125:13 + --> tests/ui/manual_is_variant_and.rs:132:13 | LL | let _ = opt.into_iter().all(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +201,7 @@ LL + let _ = opt.is_none_or(|x| x != 0); | error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:127:13 + --> tests/ui/manual_is_variant_and.rs:134:13 | LL | let _ = (opt.into_iter()).all(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +213,7 @@ LL + let _ = (opt).is_none_or(|x| x != 0); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:129:13 + --> tests/ui/manual_is_variant_and.rs:136:13 | LL | let _ = opt.into_iter().any(i32::is_negative); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +225,7 @@ LL + let _ = opt.is_some_and(i32::is_negative); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:131:13 + --> tests/ui/manual_is_variant_and.rs:138:13 | LL | let _ = opt.into_iter().any(|x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -218,7 +237,7 @@ LL + let _ = opt.is_some_and(|x| x != 0); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:135:13 + --> tests/ui/manual_is_variant_and.rs:142:13 | LL | let _ = (opt_non_copy.iter()).any(|x| x.is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +249,7 @@ LL + let _ = (opt_non_copy).as_ref().is_some_and(|x| x.is_empty()); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:137:13 + --> tests/ui/manual_is_variant_and.rs:144:13 | LL | let _ = opt_non_copy.iter().any(|x| x.is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +261,7 @@ LL + let _ = opt_non_copy.as_ref().is_some_and(|x| x.is_empty()); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:139:13 + --> tests/ui/manual_is_variant_and.rs:146:13 | LL | let _ = opt_non_copy.iter().any(|x| ".." == *x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -254,7 +273,7 @@ LL + let _ = opt_non_copy.as_ref().is_some_and(|x| ".." == *x); | error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:142:13 + --> tests/ui/manual_is_variant_and.rs:149:13 | LL | let _ = opt.iter().all(|x| *x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -266,7 +285,7 @@ LL + let _ = opt.is_none_or(|x| x != 0); | error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:144:13 + --> tests/ui/manual_is_variant_and.rs:151:13 | LL | let _ = opt.iter().all(|_| false); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -278,7 +297,7 @@ LL + let _ = opt.as_ref().is_none_or(|_| false); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:146:13 + --> tests/ui/manual_is_variant_and.rs:153:13 | LL | let _ = opt.iter().any(|&x| x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,7 +309,7 @@ LL + let _ = opt.is_some_and(|x| x != 0); | error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:148:13 + --> tests/ui/manual_is_variant_and.rs:155:13 | LL | let _ = opt.iter().all(|&_| false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +321,7 @@ LL + let _ = opt.is_none_or(|_| false); | error: use of `option::Iter::all` - --> tests/ui/manual_is_variant_and.rs:153:13 + --> tests/ui/manual_is_variant_and.rs:160:13 | LL | let _ = opt.iter().all(zerop); | ^^^^^^^^^^^^^^^^^^^^^ @@ -314,13 +333,13 @@ LL + let _ = opt.as_ref().is_none_or(zerop); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:160:18 + --> tests/ui/manual_is_variant_and.rs:167:18 | LL | let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(char::is_alphanumeric)` error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:181:17 + --> tests/ui/manual_is_variant_and.rs:188:17 | LL | let _ = res.map(|x| { | _________________^ @@ -339,7 +358,7 @@ LL ~ }); | error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:186:17 + --> tests/ui/manual_is_variant_and.rs:193:17 | LL | let _ = res.map(|x| x > 1) | _________________^ @@ -348,25 +367,25 @@ LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_ok_and(|x| x > 1)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:190:13 + --> tests/ui/manual_is_variant_and.rs:197:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:192:13 + --> tests/ui/manual_is_variant_and.rs:199:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:194:13 + --> tests/ui/manual_is_variant_and.rs:201:13 | LL | let _ = Ok::(2).map(|x| x.is_multiple_of(2)) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::(2).is_ok_and(|x| x.is_multiple_of(2))` error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:196:13 + --> tests/ui/manual_is_variant_and.rs:203:13 | LL | let _ = res.into_iter().any(i32::is_negative); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -378,7 +397,7 @@ LL + let _ = res.is_ok_and(i32::is_negative); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:198:13 + --> tests/ui/manual_is_variant_and.rs:205:13 | LL | let _ = res_non_copy.iter().any(|x| *x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -390,7 +409,7 @@ LL + let _ = res_non_copy.as_ref().is_ok_and(|x| *x != 0); | error: use of `option::Iter::any` - --> tests/ui/manual_is_variant_and.rs:200:13 + --> tests/ui/manual_is_variant_and.rs:207:13 | LL | let _ = res.iter().any(|x| *x != 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -402,106 +421,106 @@ LL + let _ = res.is_ok_and(|x| x != 0); | error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:207:18 + --> tests/ui/manual_is_variant_and.rs:214:18 | LL | let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:224:18 + --> tests/ui/manual_is_variant_and.rs:231:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| !b.is_ascii_digit())` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:231:18 + --> tests/ui/manual_is_variant_and.rs:238:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:238:18 + --> tests/ui/manual_is_variant_and.rs:245:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:245:18 + --> tests/ui/manual_is_variant_and.rs:252:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| !b.is_ascii_digit())` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:253:18 + --> tests/ui/manual_is_variant_and.rs:260:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| b.is_ascii_digit())` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:260:18 + --> tests/ui/manual_is_variant_and.rs:267:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| !b.is_ascii_digit())` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:267:18 + --> tests/ui/manual_is_variant_and.rs:274:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| b.is_ascii_digit())` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:274:18 + --> tests/ui/manual_is_variant_and.rs:281:18 | LL | let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| !b.is_ascii_digit())` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:287:18 + --> tests/ui/manual_is_variant_and.rs:294:18 | LL | let a1 = b.map(iad) == Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(iad)` error: called `.map() == Some()` - --> tests/ui/manual_is_variant_and.rs:292:18 + --> tests/ui/manual_is_variant_and.rs:299:18 | LL | let a1 = b.map(iad) == Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(|x| !iad(x))` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:297:18 + --> tests/ui/manual_is_variant_and.rs:304:18 | LL | let a1 = b.map(iad) != Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(|x| !iad(x))` error: called `.map() != Some()` - --> tests/ui/manual_is_variant_and.rs:302:18 + --> tests/ui/manual_is_variant_and.rs:309:18 | LL | let a1 = b.map(iad) != Some(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(iad)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:309:18 + --> tests/ui/manual_is_variant_and.rs:316:18 | LL | let a1 = b.map(iad) == Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(iad)` error: called `.map() == Ok()` - --> tests/ui/manual_is_variant_and.rs:314:18 + --> tests/ui/manual_is_variant_and.rs:321:18 | LL | let a1 = b.map(iad) == Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(|x| !iad(x))` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:319:18 + --> tests/ui/manual_is_variant_and.rs:326:18 | LL | let a1 = b.map(iad) != Ok(true); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(iad)` error: called `.map() != Ok()` - --> tests/ui/manual_is_variant_and.rs:324:18 + --> tests/ui/manual_is_variant_and.rs:331:18 | LL | let a1 = b.map(iad) != Ok(false); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(|x| !iad(x))` -error: aborting due to 56 previous errors +error: aborting due to 59 previous errors