@@ -3,6 +3,7 @@ use clippy_utils::eager_or_lazy::switch_to_eager_eval;
33use clippy_utils:: path_to_local_id;
44use clippy_utils:: source:: snippet;
55use clippy_utils:: ty:: is_type_diagnostic_item;
6+ use clippy_utils:: visitors:: is_local_used;
67use rustc_ast:: LitKind :: Bool ;
78use rustc_errors:: Applicability ;
89use rustc_hir:: { BinOpKind , Expr , ExprKind , PatKind } ;
@@ -14,20 +15,13 @@ use super::UNNECESSARY_PATTERN_MATCHING;
1415// Only checking map_or for now
1516pub ( super ) fn check ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , recv : & Expr < ' _ > , def : & Expr < ' _ > , map : & Expr < ' _ > ) {
1617 if let ExprKind :: Lit ( def_kind) = def. kind
17- // only works on Result and Option
1818 && let recv_ty = cx. typeck_results ( ) . expr_ty ( recv)
1919 && ( is_type_diagnostic_item ( cx, recv_ty, sym:: Option )
2020 || is_type_diagnostic_item ( cx, recv_ty, sym:: Result ) )
21- // check we are dealing with boolean map_or
2221 && let Bool ( def_bool) = def_kind. node
2322 && let ExprKind :: Closure ( map_closure) = map. kind
2423 && let closure_body = cx. tcx . hir ( ) . body ( map_closure. body )
2524 && let closure_body_value = closure_body. value . peel_blocks ( )
26- // switching from closure to direct comparison changes the comparison
27- // from lazy (when map_or evaluates to first param) to eager, so we force eager here
28- // this stops the lint running whenever the closure has a potentially expensive
29- // computation inside of it
30- && switch_to_eager_eval ( cx, closure_body_value)
3125 && let ExprKind :: Binary ( op, l, r) = closure_body_value. kind
3226 && let Some ( param) = closure_body. params . first ( )
3327 && let PatKind :: Binding ( _, hir_id, _, _) = param. pat . kind
@@ -45,17 +39,21 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def:
4539 } else {
4640 "Result"
4741 } ;
48-
4942 let comparator = if BinOpKind :: Eq == op. node { "==" } else { "!=" } ;
50-
5143 // we already checked either l or r is the local id earlier
5244 let non_binding_location = if path_to_local_id ( l, hir_id) { r } else { l } ;
53-
45+ // we switch to eager in the event that the closure has an
46+ // expensive computation inside of it
47+ if is_local_used ( cx, non_binding_location, hir_id)
48+ || !switch_to_eager_eval ( cx, non_binding_location)
49+ || l. kind {
50+ return ;
51+ } ;
5452 span_lint_and_sugg (
5553 cx,
5654 UNNECESSARY_PATTERN_MATCHING ,
5755 expr. span ,
58- "`map_or` here is redundant, use standard comparison instead" ,
56+ "`map_or` is redundant, use standard comparison instead" ,
5957 "try" ,
6058 format ! (
6159 "{} {} {}({})" ,
0 commit comments