From 9a55c0c1763cc5894ce1dbf1c40d03119e3de5f3 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 15 Apr 2021 22:05:37 -0400 Subject: [PATCH] Fix `single_match` Check for `PartialEq` in addition to `StructuralPartialEq` before suggesting `==` --- clippy_lints/src/matches.rs | 7 +++++-- tests/ui/single_match.rs | 8 ++++++++ tests/ui/single_match.stderr | 11 ++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 8f1112cff7b1..e4d1451b3691 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -738,8 +738,11 @@ fn report_single_match_single_pattern( let (msg, sugg) = if_chain! { if let PatKind::Path(_) | PatKind::Lit(_) = pat.kind; let (ty, ty_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(ex)); - if let Some(trait_id) = cx.tcx.lang_items().structural_peq_trait(); - if ty.is_integral() || ty.is_char() || ty.is_str() || implements_trait(cx, ty, trait_id, &[]); + if let Some(spe_trait_id) = cx.tcx.lang_items().structural_peq_trait(); + if let Some(pe_trait_id) = cx.tcx.lang_items().eq_trait(); + if ty.is_integral() || ty.is_char() || ty.is_str() + || (implements_trait(cx, ty, spe_trait_id, &[]) + && implements_trait(cx, ty, pe_trait_id, &[ty.into()])); then { // scrutinee derives PartialEq and the pattern is a constant. let pat_ref_count = match pat.kind { diff --git a/tests/ui/single_match.rs b/tests/ui/single_match.rs index ca884b41c457..b1819e08d53b 100644 --- a/tests/ui/single_match.rs +++ b/tests/ui/single_match.rs @@ -135,6 +135,14 @@ fn if_suggestion() { Bar::A => println!(), _ => (), } + + // issue #7038 + struct X; + let x = Some(X); + match x { + None => println!(), + _ => (), + }; } macro_rules! single_match { diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr index 7ea6955b7401..9ef2a8668a6f 100644 --- a/tests/ui/single_match.stderr +++ b/tests/ui/single_match.stderr @@ -119,5 +119,14 @@ LL | | _ => (), LL | | } | |_____^ help: try this: `if let Bar::A = x { println!() }` -error: aborting due to 12 previous errors +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match.rs:142:5 + | +LL | / match x { +LL | | None => println!(), +LL | | _ => (), +LL | | }; + | |_____^ help: try this: `if let None = x { println!() }` + +error: aborting due to 13 previous errors