Lint suggests matches macro if PartialEq trait is not implemented

This commit is contained in:
Nahua Kang 2022-08-23 19:46:04 +02:00
parent a6444a69e2
commit 5ee1c24f28
2 changed files with 47 additions and 24 deletions

View file

@ -68,31 +68,47 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if !in_external_macro(cx.sess(), expr.span)
&& let ExprKind::Let(let_expr) = expr.kind
&& unary_pattern(let_expr.pat)
&& let exp_ty = cx.typeck_results().expr_ty(let_expr.init)
&& let pat_ty = cx.typeck_results().pat_ty(let_expr.pat)
&& is_structural_partial_eq(cx, exp_ty, pat_ty) {
&& unary_pattern(let_expr.pat) {
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
let mut applicability = Applicability::MachineApplicable;
let pat_str = match let_expr.pat.kind {
PatKind::Struct(..) => format!(
"({})",
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
),
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
};
span_lint_and_sugg(
cx,
EQUATABLE_IF_LET,
expr.span,
"this pattern matching can be expressed using equality",
"try",
format!(
"{} == {}",
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
pat_str,
),
applicability,
);
if is_structural_partial_eq(cx, exp_ty, pat_ty) {
let pat_str = match let_expr.pat.kind {
PatKind::Struct(..) => format!(
"({})",
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
),
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
};
span_lint_and_sugg(
cx,
EQUATABLE_IF_LET,
expr.span,
"this pattern matching can be expressed using equality",
"try",
format!(
"{} == {}",
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
pat_str,
),
applicability,
);
} else {
span_lint_and_sugg(
cx,
EQUATABLE_IF_LET,
expr.span,
"this pattern matching can be expressed using `matches!`",
"try",
format!(
"matches!({}, {})",
snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
),
applicability,
)
}
}
}
}

View file

@ -23,6 +23,11 @@ struct Struct {
b: bool,
}
struct NoPartialEqStruct {
a: i32,
b: bool,
}
enum NotPartialEq {
A,
B,
@ -47,6 +52,7 @@ fn main() {
let e = Enum::UnitVariant;
let f = NotPartialEq::A;
let g = NotStructuralEq::A;
let h = NoPartialEqStruct { a: 2, b: false };
// true
@ -70,6 +76,7 @@ fn main() {
if let NotStructuralEq::A = g {}
if let Some(NotPartialEq::A) = Some(f) {}
if let Some(NotStructuralEq::A) = Some(g) {}
if let NoPartialEqStruct { a: 2, b: false } = h {}
macro_rules! m1 {
(x) => {