mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-08 01:28:18 +03:00
Make obfuscated_if_else a bit more type-safe
This commit is contained in:
@@ -5501,7 +5501,14 @@ fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv);
|
||||
},
|
||||
Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {
|
||||
obfuscated_if_else::check(cx, expr, t_recv, t_arg, Some(u_arg), then_method, name);
|
||||
obfuscated_if_else::check(
|
||||
cx,
|
||||
expr,
|
||||
t_recv,
|
||||
t_arg,
|
||||
then_method,
|
||||
obfuscated_if_else::Unwrap::Or(u_arg),
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@@ -5518,9 +5525,8 @@ fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
expr,
|
||||
t_recv,
|
||||
t_arg,
|
||||
None,
|
||||
then_method,
|
||||
sym::unwrap_or_default,
|
||||
obfuscated_if_else::Unwrap::OrDefault,
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
@@ -5537,9 +5543,8 @@ fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
expr,
|
||||
t_recv,
|
||||
t_arg,
|
||||
Some(u_arg),
|
||||
then_method,
|
||||
sym::unwrap_or_else,
|
||||
obfuscated_if_else::Unwrap::OrElse(u_arg),
|
||||
);
|
||||
},
|
||||
_ => {
|
||||
|
||||
@@ -5,25 +5,24 @@
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{get_parent_expr, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::ExprKind;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
#[expect(clippy::needless_pass_by_value)]
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx hir::Expr<'_>,
|
||||
then_recv: &'tcx hir::Expr<'_>,
|
||||
then_arg: &'tcx hir::Expr<'_>,
|
||||
unwrap_arg: Option<&'tcx hir::Expr<'_>>,
|
||||
expr: &'tcx Expr<'_>,
|
||||
then_recv: &'tcx Expr<'_>,
|
||||
then_arg: &'tcx Expr<'_>,
|
||||
then_method_name: Symbol,
|
||||
unwrap_method_name: Symbol,
|
||||
unwrap: Unwrap<'tcx>,
|
||||
) {
|
||||
let recv_ty = cx.typeck_results().expr_ty(then_recv);
|
||||
|
||||
if recv_ty.is_bool() {
|
||||
let then_eager = switch_to_eager_eval(cx, then_arg);
|
||||
let unwrap_eager = unwrap_arg.is_none_or(|arg| switch_to_eager_eval(cx, arg));
|
||||
let unwrap_eager = unwrap.arg().is_none_or(|arg| switch_to_eager_eval(cx, arg));
|
||||
|
||||
let mut applicability = if then_eager && unwrap_eager {
|
||||
Applicability::MachineApplicable
|
||||
@@ -40,18 +39,17 @@ pub(super) fn check<'tcx>(
|
||||
_ => return,
|
||||
};
|
||||
|
||||
// FIXME: Add `unwrap_or_else` and `unwrap_or_default` symbol
|
||||
let els = match unwrap_method_name {
|
||||
sym::unwrap_or => snippet_with_applicability(cx, unwrap_arg.unwrap().span, "..", &mut applicability),
|
||||
sym::unwrap_or_else if let ExprKind::Closure(closure) = unwrap_arg.unwrap().kind => {
|
||||
let body = cx.tcx.hir_body(closure.body);
|
||||
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
|
||||
let els = match unwrap {
|
||||
Unwrap::Or(arg) => snippet_with_applicability(cx, arg.span, "..", &mut applicability),
|
||||
Unwrap::OrElse(arg) => match arg.kind {
|
||||
ExprKind::Closure(closure) => {
|
||||
let body = cx.tcx.hir_body(closure.body);
|
||||
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
|
||||
},
|
||||
ExprKind::Path(_) => snippet_with_applicability(cx, arg.span, "_", &mut applicability) + "()",
|
||||
_ => return,
|
||||
},
|
||||
sym::unwrap_or_else if let ExprKind::Path(_) = unwrap_arg.unwrap().kind => {
|
||||
snippet_with_applicability(cx, unwrap_arg.unwrap().span, "_", &mut applicability) + "()"
|
||||
},
|
||||
sym::unwrap_or_default => "Default::default()".into(),
|
||||
_ => return,
|
||||
Unwrap::OrDefault => "Default::default()".into(),
|
||||
};
|
||||
|
||||
let sugg = format!(
|
||||
@@ -83,3 +81,18 @@ pub(super) fn check<'tcx>(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) enum Unwrap<'tcx> {
|
||||
Or(&'tcx Expr<'tcx>),
|
||||
OrElse(&'tcx Expr<'tcx>),
|
||||
OrDefault,
|
||||
}
|
||||
|
||||
impl<'tcx> Unwrap<'tcx> {
|
||||
fn arg(&self) -> Option<&'tcx Expr<'tcx>> {
|
||||
match self {
|
||||
Self::Or(a) | Self::OrElse(a) => Some(a),
|
||||
Self::OrDefault => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user