Auto merge of #10139 - chansuke:chore/fix-if_chain_ident, r=Jarcho
chore: fix identation of `if_chain` in `filter_map`
This is a really small fix.
If someone could take a look at it, I would appreciate it🙏
---
changelog: none
<!-- changelog_checked -->
This commit is contained in:
commit
653f5d98d8
@ -30,12 +30,12 @@ fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) ->
|
|||||||
match closure_expr.kind {
|
match closure_expr.kind {
|
||||||
hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, receiver, ..) => {
|
hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, receiver, ..) => {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if ident.name == method_name;
|
if ident.name == method_name;
|
||||||
if let hir::ExprKind::Path(path) = &receiver.kind;
|
if let hir::ExprKind::Path(path) = &receiver.kind;
|
||||||
if let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id);
|
if let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id);
|
||||||
then {
|
then {
|
||||||
return arg_id == *local
|
return arg_id == *local
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
@ -92,92 +92,92 @@ pub(super) fn check(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if is_trait_method(cx, map_recv, sym::Iterator);
|
if is_trait_method(cx, map_recv, sym::Iterator);
|
||||||
|
|
||||||
// filter(|x| ...is_some())...
|
// filter(|x| ...is_some())...
|
||||||
if let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind;
|
if let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind;
|
||||||
let filter_body = cx.tcx.hir().body(filter_body_id);
|
let filter_body = cx.tcx.hir().body(filter_body_id);
|
||||||
if let [filter_param] = filter_body.params;
|
if let [filter_param] = filter_body.params;
|
||||||
// optional ref pattern: `filter(|&x| ..)`
|
// optional ref pattern: `filter(|&x| ..)`
|
||||||
let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind {
|
let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind {
|
||||||
(ref_pat, true)
|
(ref_pat, true)
|
||||||
|
} else {
|
||||||
|
(filter_param.pat, false)
|
||||||
|
};
|
||||||
|
// closure ends with is_some() or is_ok()
|
||||||
|
if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind;
|
||||||
|
if let ExprKind::MethodCall(path, filter_arg, [], _) = filter_body.value.kind;
|
||||||
|
if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).peel_refs().ty_adt_def();
|
||||||
|
if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did()) {
|
||||||
|
Some(false)
|
||||||
|
} else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did()) {
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" };
|
||||||
|
|
||||||
|
// ...map(|x| ...unwrap())
|
||||||
|
if let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind;
|
||||||
|
let map_body = cx.tcx.hir().body(map_body_id);
|
||||||
|
if let [map_param] = map_body.params;
|
||||||
|
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;
|
||||||
|
// closure ends with expect() or unwrap()
|
||||||
|
if let ExprKind::MethodCall(seg, map_arg, ..) = map_body.value.kind;
|
||||||
|
if matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or);
|
||||||
|
|
||||||
|
// .filter(..).map(|y| f(y).copied().unwrap())
|
||||||
|
// ~~~~
|
||||||
|
let map_arg_peeled = match map_arg.kind {
|
||||||
|
ExprKind::MethodCall(method, original_arg, [], _) if acceptable_methods(method) => {
|
||||||
|
original_arg
|
||||||
|
},
|
||||||
|
_ => map_arg,
|
||||||
|
};
|
||||||
|
|
||||||
|
// .filter(|x| x.is_some()).map(|y| y[.acceptable_method()].unwrap())
|
||||||
|
let simple_equal = path_to_local_id(filter_arg, filter_param_id)
|
||||||
|
&& path_to_local_id(map_arg_peeled, map_param_id);
|
||||||
|
|
||||||
|
let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| {
|
||||||
|
// in `filter(|x| ..)`, replace `*x` with `x`
|
||||||
|
let a_path = if_chain! {
|
||||||
|
if !is_filter_param_ref;
|
||||||
|
if let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind;
|
||||||
|
then { expr_path } else { a }
|
||||||
|
};
|
||||||
|
// let the filter closure arg and the map closure arg be equal
|
||||||
|
path_to_local_id(a_path, filter_param_id)
|
||||||
|
&& path_to_local_id(b, map_param_id)
|
||||||
|
&& cx.typeck_results().expr_ty_adjusted(a) == cx.typeck_results().expr_ty_adjusted(b)
|
||||||
|
};
|
||||||
|
|
||||||
|
if simple_equal || SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(filter_arg, map_arg_peeled);
|
||||||
|
then {
|
||||||
|
let span = filter_span.with_hi(expr.span.hi());
|
||||||
|
let (filter_name, lint) = if is_find {
|
||||||
|
("find", MANUAL_FIND_MAP)
|
||||||
} else {
|
} else {
|
||||||
(filter_param.pat, false)
|
("filter", MANUAL_FILTER_MAP)
|
||||||
};
|
};
|
||||||
// closure ends with is_some() or is_ok()
|
let msg = format!("`{filter_name}(..).map(..)` can be simplified as `{filter_name}_map(..)`");
|
||||||
if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind;
|
let (to_opt, deref) = if is_result {
|
||||||
if let ExprKind::MethodCall(path, filter_arg, [], _) = filter_body.value.kind;
|
(".ok()", String::new())
|
||||||
if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).peel_refs().ty_adt_def();
|
|
||||||
if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did()) {
|
|
||||||
Some(false)
|
|
||||||
} else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did()) {
|
|
||||||
Some(true)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
let derefs = cx.typeck_results()
|
||||||
|
.expr_adjustments(map_arg)
|
||||||
|
.iter()
|
||||||
|
.filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
|
||||||
|
.count();
|
||||||
|
|
||||||
|
("", "*".repeat(derefs))
|
||||||
};
|
};
|
||||||
if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" };
|
let sugg = format!(
|
||||||
|
"{filter_name}_map(|{map_param_ident}| {deref}{}{to_opt})",
|
||||||
// ...map(|x| ...unwrap())
|
snippet(cx, map_arg.span, ".."),
|
||||||
if let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind;
|
);
|
||||||
let map_body = cx.tcx.hir().body(map_body_id);
|
span_lint_and_sugg(cx, lint, span, &msg, "try", sugg, Applicability::MachineApplicable);
|
||||||
if let [map_param] = map_body.params;
|
}
|
||||||
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;
|
|
||||||
// closure ends with expect() or unwrap()
|
|
||||||
if let ExprKind::MethodCall(seg, map_arg, ..) = map_body.value.kind;
|
|
||||||
if matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or);
|
|
||||||
|
|
||||||
// .filter(..).map(|y| f(y).copied().unwrap())
|
|
||||||
// ~~~~
|
|
||||||
let map_arg_peeled = match map_arg.kind {
|
|
||||||
ExprKind::MethodCall(method, original_arg, [], _) if acceptable_methods(method) => {
|
|
||||||
original_arg
|
|
||||||
},
|
|
||||||
_ => map_arg,
|
|
||||||
};
|
|
||||||
|
|
||||||
// .filter(|x| x.is_some()).map(|y| y[.acceptable_method()].unwrap())
|
|
||||||
let simple_equal = path_to_local_id(filter_arg, filter_param_id)
|
|
||||||
&& path_to_local_id(map_arg_peeled, map_param_id);
|
|
||||||
|
|
||||||
let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| {
|
|
||||||
// in `filter(|x| ..)`, replace `*x` with `x`
|
|
||||||
let a_path = if_chain! {
|
|
||||||
if !is_filter_param_ref;
|
|
||||||
if let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind;
|
|
||||||
then { expr_path } else { a }
|
|
||||||
};
|
|
||||||
// let the filter closure arg and the map closure arg be equal
|
|
||||||
path_to_local_id(a_path, filter_param_id)
|
|
||||||
&& path_to_local_id(b, map_param_id)
|
|
||||||
&& cx.typeck_results().expr_ty_adjusted(a) == cx.typeck_results().expr_ty_adjusted(b)
|
|
||||||
};
|
|
||||||
|
|
||||||
if simple_equal || SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(filter_arg, map_arg_peeled);
|
|
||||||
then {
|
|
||||||
let span = filter_span.with_hi(expr.span.hi());
|
|
||||||
let (filter_name, lint) = if is_find {
|
|
||||||
("find", MANUAL_FIND_MAP)
|
|
||||||
} else {
|
|
||||||
("filter", MANUAL_FILTER_MAP)
|
|
||||||
};
|
|
||||||
let msg = format!("`{filter_name}(..).map(..)` can be simplified as `{filter_name}_map(..)`");
|
|
||||||
let (to_opt, deref) = if is_result {
|
|
||||||
(".ok()", String::new())
|
|
||||||
} else {
|
|
||||||
let derefs = cx.typeck_results()
|
|
||||||
.expr_adjustments(map_arg)
|
|
||||||
.iter()
|
|
||||||
.filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
|
|
||||||
.count();
|
|
||||||
|
|
||||||
("", "*".repeat(derefs))
|
|
||||||
};
|
|
||||||
let sugg = format!(
|
|
||||||
"{filter_name}_map(|{map_param_ident}| {deref}{}{to_opt})",
|
|
||||||
snippet(cx, map_arg.span, ".."),
|
|
||||||
);
|
|
||||||
span_lint_and_sugg(cx, lint, span, &msg, "try", sugg, Applicability::MachineApplicable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user