Skip to content

Commit 5ee1c24

Browse files
committed
Lint suggests matches macro if PartialEq trait is not implemented
1 parent a6444a6 commit 5ee1c24

File tree

2 files changed

+47
-24
lines changed

2 files changed

+47
-24
lines changed

clippy_lints/src/equatable_if_let.rs

+40-24
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,47 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
6868
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
6969
if !in_external_macro(cx.sess(), expr.span)
7070
&& let ExprKind::Let(let_expr) = expr.kind
71-
&& unary_pattern(let_expr.pat)
72-
&& let exp_ty = cx.typeck_results().expr_ty(let_expr.init)
73-
&& let pat_ty = cx.typeck_results().pat_ty(let_expr.pat)
74-
&& is_structural_partial_eq(cx, exp_ty, pat_ty) {
71+
&& unary_pattern(let_expr.pat) {
72+
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
73+
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
7574
let mut applicability = Applicability::MachineApplicable;
76-
let pat_str = match let_expr.pat.kind {
77-
PatKind::Struct(..) => format!(
78-
"({})",
79-
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
80-
),
81-
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
82-
};
83-
span_lint_and_sugg(
84-
cx,
85-
EQUATABLE_IF_LET,
86-
expr.span,
87-
"this pattern matching can be expressed using equality",
88-
"try",
89-
format!(
90-
"{} == {}",
91-
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
92-
pat_str,
93-
),
94-
applicability,
95-
);
75+
76+
if is_structural_partial_eq(cx, exp_ty, pat_ty) {
77+
let pat_str = match let_expr.pat.kind {
78+
PatKind::Struct(..) => format!(
79+
"({})",
80+
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
81+
),
82+
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
83+
};
84+
span_lint_and_sugg(
85+
cx,
86+
EQUATABLE_IF_LET,
87+
expr.span,
88+
"this pattern matching can be expressed using equality",
89+
"try",
90+
format!(
91+
"{} == {}",
92+
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
93+
pat_str,
94+
),
95+
applicability,
96+
);
97+
} else {
98+
span_lint_and_sugg(
99+
cx,
100+
EQUATABLE_IF_LET,
101+
expr.span,
102+
"this pattern matching can be expressed using `matches!`",
103+
"try",
104+
format!(
105+
"matches!({}, {})",
106+
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
107+
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
108+
),
109+
applicability,
110+
)
111+
}
96112
}
97113
}
98114
}

tests/ui/equatable_if_let.rs

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ struct Struct {
2323
b: bool,
2424
}
2525

26+
struct NoPartialEqStruct {
27+
a: i32,
28+
b: bool,
29+
}
30+
2631
enum NotPartialEq {
2732
A,
2833
B,
@@ -47,6 +52,7 @@ fn main() {
4752
let e = Enum::UnitVariant;
4853
let f = NotPartialEq::A;
4954
let g = NotStructuralEq::A;
55+
let h = NoPartialEqStruct { a: 2, b: false };
5056

5157
// true
5258

@@ -70,6 +76,7 @@ fn main() {
7076
if let NotStructuralEq::A = g {}
7177
if let Some(NotPartialEq::A) = Some(f) {}
7278
if let Some(NotStructuralEq::A) = Some(g) {}
79+
if let NoPartialEqStruct { a: 2, b: false } = h {}
7380

7481
macro_rules! m1 {
7582
(x) => {

0 commit comments

Comments
 (0)