Skip to content

Commit 7b0c3d0

Browse files
authored
refactor(obfuscated_if_else): make a bit more type-safe (#15846)
changelog: none
2 parents 30c73fe + d1be6d8 commit 7b0c3d0

File tree

2 files changed

+42
-24
lines changed

2 files changed

+42
-24
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5501,7 +5501,14 @@ impl Methods {
55015501
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv);
55025502
},
55035503
Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {
5504-
obfuscated_if_else::check(cx, expr, t_recv, t_arg, Some(u_arg), then_method, name);
5504+
obfuscated_if_else::check(
5505+
cx,
5506+
expr,
5507+
t_recv,
5508+
t_arg,
5509+
then_method,
5510+
obfuscated_if_else::Unwrap::Or(u_arg),
5511+
);
55055512
},
55065513
_ => {},
55075514
}
@@ -5518,9 +5525,8 @@ impl Methods {
55185525
expr,
55195526
t_recv,
55205527
t_arg,
5521-
None,
55225528
then_method,
5523-
sym::unwrap_or_default,
5529+
obfuscated_if_else::Unwrap::OrDefault,
55245530
);
55255531
},
55265532
_ => {},
@@ -5537,9 +5543,8 @@ impl Methods {
55375543
expr,
55385544
t_recv,
55395545
t_arg,
5540-
Some(u_arg),
55415546
then_method,
5542-
sym::unwrap_or_else,
5547+
obfuscated_if_else::Unwrap::OrElse(u_arg),
55435548
);
55445549
},
55455550
_ => {

clippy_lints/src/methods/obfuscated_if_else.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,24 @@ use clippy_utils::source::snippet_with_applicability;
55
use clippy_utils::sugg::Sugg;
66
use clippy_utils::{get_parent_expr, sym};
77
use rustc_errors::Applicability;
8-
use rustc_hir as hir;
9-
use rustc_hir::ExprKind;
8+
use rustc_hir::{Expr, ExprKind};
109
use rustc_lint::LateContext;
1110
use rustc_span::Symbol;
1211

12+
#[expect(clippy::needless_pass_by_value)]
1313
pub(super) fn check<'tcx>(
1414
cx: &LateContext<'tcx>,
15-
expr: &'tcx hir::Expr<'_>,
16-
then_recv: &'tcx hir::Expr<'_>,
17-
then_arg: &'tcx hir::Expr<'_>,
18-
unwrap_arg: Option<&'tcx hir::Expr<'_>>,
15+
expr: &'tcx Expr<'_>,
16+
then_recv: &'tcx Expr<'_>,
17+
then_arg: &'tcx Expr<'_>,
1918
then_method_name: Symbol,
20-
unwrap_method_name: Symbol,
19+
unwrap: Unwrap<'tcx>,
2120
) {
2221
let recv_ty = cx.typeck_results().expr_ty(then_recv);
2322

2423
if recv_ty.is_bool() {
2524
let then_eager = switch_to_eager_eval(cx, then_arg);
26-
let unwrap_eager = unwrap_arg.is_none_or(|arg| switch_to_eager_eval(cx, arg));
25+
let unwrap_eager = unwrap.arg().is_none_or(|arg| switch_to_eager_eval(cx, arg));
2726

2827
let mut applicability = if then_eager && unwrap_eager {
2928
Applicability::MachineApplicable
@@ -40,18 +39,17 @@ pub(super) fn check<'tcx>(
4039
_ => return,
4140
};
4241

43-
// FIXME: Add `unwrap_or_else` and `unwrap_or_default` symbol
44-
let els = match unwrap_method_name {
45-
sym::unwrap_or => snippet_with_applicability(cx, unwrap_arg.unwrap().span, "..", &mut applicability),
46-
sym::unwrap_or_else if let ExprKind::Closure(closure) = unwrap_arg.unwrap().kind => {
47-
let body = cx.tcx.hir_body(closure.body);
48-
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
49-
},
50-
sym::unwrap_or_else if let ExprKind::Path(_) = unwrap_arg.unwrap().kind => {
51-
snippet_with_applicability(cx, unwrap_arg.unwrap().span, "_", &mut applicability) + "()"
42+
let els = match unwrap {
43+
Unwrap::Or(arg) => snippet_with_applicability(cx, arg.span, "..", &mut applicability),
44+
Unwrap::OrElse(arg) => match arg.kind {
45+
ExprKind::Closure(closure) => {
46+
let body = cx.tcx.hir_body(closure.body);
47+
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
48+
},
49+
ExprKind::Path(_) => snippet_with_applicability(cx, arg.span, "_", &mut applicability) + "()",
50+
_ => return,
5251
},
53-
sym::unwrap_or_default => "Default::default()".into(),
54-
_ => return,
52+
Unwrap::OrDefault => "Default::default()".into(),
5553
};
5654

5755
let sugg = format!(
@@ -83,3 +81,18 @@ pub(super) fn check<'tcx>(
8381
);
8482
}
8583
}
84+
85+
pub(super) enum Unwrap<'tcx> {
86+
Or(&'tcx Expr<'tcx>),
87+
OrElse(&'tcx Expr<'tcx>),
88+
OrDefault,
89+
}
90+
91+
impl<'tcx> Unwrap<'tcx> {
92+
fn arg(&self) -> Option<&'tcx Expr<'tcx>> {
93+
match self {
94+
Self::Or(a) | Self::OrElse(a) => Some(a),
95+
Self::OrDefault => None,
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)