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>,
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());
}
}
- 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),
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);
+ }
+ }
}