extend obfuscated_if_else to support then().unwrap_or_else() and then_some().unwrap_or_else()

This commit is contained in:
lapla-cogito 2025-02-06 23:42:03 +09:00
parent 649cef0e81
commit 6c6ffd27a2
No known key found for this signature in database
GPG key ID: B39C71D9F127FF9F
5 changed files with 111 additions and 20 deletions

View file

@ -5398,7 +5398,7 @@ impl Methods {
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv);
},
Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => {
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method);
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or");
},
_ => {},
}
@ -5417,6 +5417,9 @@ impl Methods {
match method_call(recv) {
Some(("map", recv, [map_arg], _, _))
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {},
Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => {
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or_else");
},
_ => {
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
},

View file

@ -16,6 +16,7 @@ pub(super) fn check<'tcx>(
then_arg: &'tcx hir::Expr<'_>,
unwrap_arg: &'tcx hir::Expr<'_>,
then_method_name: &str,
unwrap_method_name: &str,
) {
let recv_ty = cx.typeck_results().expr_ty(then_recv);
@ -32,14 +33,27 @@ pub(super) fn check<'tcx>(
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
},
"then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability),
_ => String::new().into(),
_ => return,
};
// FIXME: Add `unwrap_or_else` symbol
let els = match unwrap_method_name {
"unwrap_or" => snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability),
"unwrap_or_else" if let ExprKind::Closure(closure) = unwrap_arg.kind => {
let body = cx.tcx.hir_body(closure.body);
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
},
"unwrap_or_else" if let ExprKind::Path(_) = unwrap_arg.kind => {
snippet_with_applicability(cx, unwrap_arg.span, "_", &mut applicability) + "()"
},
_ => return,
};
let sugg = format!(
"if {} {{ {} }} else {{ {} }}",
Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability),
if_then,
snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability)
els
);
// To be parsed as an expression, the `if { … } else { … }` as the left operand of a binary operator