]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
Rollup merge of #105663 - andrewpollack:patch-1, r=tmandry
[rust.git] / src / tools / clippy / clippy_lints / src / methods / or_fun_call.rs
index 991d3dd538bf86a7ea572c011cd419fb1aa22999..4460f38fcc18f8ff5743eda8ecdbb1347617ce88 100644 (file)
@@ -83,6 +83,8 @@ fn check_general_case<'tcx>(
         method_span: Span,
         self_expr: &hir::Expr<'_>,
         arg: &'tcx hir::Expr<'_>,
+        // `Some` if fn has second argument
+        second_arg: Option<&hir::Expr<'_>>,
         span: Span,
         // None if lambda is required
         fun_span: Option<Span>,
@@ -109,30 +111,40 @@ fn check_general_case<'tcx>(
             if poss.contains(&name);
 
             then {
-                let macro_expanded_snipped;
-                let sugg: Cow<'_, str> = {
+                let sugg = {
                     let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) {
                         (false, Some(fun_span)) => (fun_span, false),
                         _ => (arg.span, true),
                     };
-                    let snippet = {
-                        let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, "..");
-                        if not_macro_argument_snippet == "vec![]" {
-                            macro_expanded_snipped = snippet(cx, snippet_span, "..");
+
+                    let format_span = |span: Span| {
+                        let not_macro_argument_snippet = snippet_with_macro_callsite(cx, span, "..");
+                        let snip = if not_macro_argument_snippet == "vec![]" {
+                            let macro_expanded_snipped = snippet(cx, snippet_span, "..");
                             match macro_expanded_snipped.strip_prefix("$crate::vec::") {
-                                Some(stripped) => Cow::from(stripped),
+                                Some(stripped) => Cow::Owned(stripped.to_owned()),
                                 None => macro_expanded_snipped,
                             }
                         } else {
                             not_macro_argument_snippet
-                        }
+                        };
+
+                        snip.to_string()
                     };
 
-                    if use_lambda {
+                    let snip = format_span(snippet_span);
+                    let snip = if use_lambda {
                         let l_arg = if fn_has_arguments { "_" } else { "" };
-                        format!("|{l_arg}| {snippet}").into()
+                        format!("|{l_arg}| {snip}")
                     } else {
-                        snippet
+                        snip
+                    };
+
+                    if let Some(f) = second_arg {
+                        let f = format_span(f.span);
+                        format!("{snip}, {f}")
+                    } else {
+                        snip
                     }
                 };
                 let span_replace_word = method_span.with_hi(span.hi());
@@ -149,8 +161,8 @@ fn check_general_case<'tcx>(
         }
     }
 
-    if let [arg] = args {
-        let inner_arg = if let hir::ExprKind::Block(
+    let extract_inner_arg = |arg: &'tcx hir::Expr<'_>| {
+        if let hir::ExprKind::Block(
             hir::Block {
                 stmts: [],
                 expr: Some(expr),
@@ -162,19 +174,32 @@ fn check_general_case<'tcx>(
             expr
         } else {
             arg
-        };
+        }
+    };
+
+    if let [arg] = args {
+        let inner_arg = extract_inner_arg(arg);
         match inner_arg.kind {
             hir::ExprKind::Call(fun, or_args) => {
                 let or_has_args = !or_args.is_empty();
                 if !check_unwrap_or_default(cx, name, fun, arg, or_has_args, expr.span, method_span) {
                     let fun_span = if or_has_args { None } else { Some(fun.span) };
-                    check_general_case(cx, name, method_span, receiver, arg, expr.span, fun_span);
+                    check_general_case(cx, name, method_span, receiver, arg, None, expr.span, fun_span);
                 }
             },
             hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
-                check_general_case(cx, name, method_span, receiver, arg, expr.span, None);
+                check_general_case(cx, name, method_span, receiver, arg, None, expr.span, None);
             },
             _ => (),
         }
     }
+
+    // `map_or` takes two arguments
+    if let [arg, lambda] = args {
+        let inner_arg = extract_inner_arg(arg);
+        if let hir::ExprKind::Call(fun, or_args) = inner_arg.kind {
+            let fun_span = if or_args.is_empty() { Some(fun.span) } else { None };
+            check_general_case(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span);
+        }
+    }
 }