1+ use clippy_config:: Conf ;
12use clippy_utils:: diagnostics:: span_lint_and_sugg;
23use clippy_utils:: is_in_const_context;
4+ use clippy_utils:: msrvs:: Msrv ;
5+ use clippy_utils:: qualify_min_const_fn:: is_stable_const_fn;
36use clippy_utils:: source:: snippet_with_context;
47use clippy_utils:: ty:: implements_trait;
58use rustc_errors:: Applicability ;
69use rustc_hir:: { Expr , ExprKind , Pat , PatKind } ;
710use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
811use rustc_middle:: ty:: Ty ;
9- use rustc_session:: declare_lint_pass ;
12+ use rustc_session:: impl_lint_pass ;
1013
1114declare_clippy_lint ! {
1215 /// ### What it does
@@ -38,7 +41,17 @@ declare_clippy_lint! {
3841 "using pattern matching instead of equality"
3942}
4043
41- declare_lint_pass ! ( PatternEquality => [ EQUATABLE_IF_LET ] ) ;
44+ impl_lint_pass ! ( PatternEquality => [ EQUATABLE_IF_LET ] ) ;
45+
46+ pub ( super ) struct PatternEquality {
47+ msrv : Msrv ,
48+ }
49+
50+ impl PatternEquality {
51+ pub ( super ) fn new ( conf : & Conf ) -> Self {
52+ Self { msrv : conf. msrv }
53+ }
54+ }
4255
4356/// detects if pattern matches just one thing
4457fn unary_pattern ( pat : & Pat < ' _ > ) -> bool {
@@ -61,9 +74,21 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
6174 }
6275}
6376
64- fn is_structural_partial_eq < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , other : Ty < ' tcx > ) -> bool {
65- if let Some ( def_id) = cx. tcx . lang_items ( ) . eq_trait ( ) {
66- implements_trait ( cx, ty, def_id, & [ other. into ( ) ] )
77+ fn is_structural_partial_eq < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , other : Ty < ' tcx > , msrv : Msrv ) -> bool {
78+ if let Some ( eq_trait) = cx. tcx . lang_items ( ) . eq_trait ( )
79+ && implements_trait ( cx, ty, eq_trait, & [ other. into ( ) ] )
80+ {
81+ if !is_in_const_context ( cx) {
82+ return true ;
83+ }
84+
85+ if let Some ( eq_method) = cx. tcx . provided_trait_methods ( eq_trait) . next ( )
86+ && is_stable_const_fn ( cx, eq_method. def_id , msrv)
87+ {
88+ true
89+ } else {
90+ false
91+ }
6792 } else {
6893 false
6994 }
@@ -106,13 +131,12 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
106131 if let ExprKind :: Let ( let_expr) = expr. kind
107132 && unary_pattern ( let_expr. pat )
108133 && !expr. span . in_external_macro ( cx. sess ( ) . source_map ( ) )
109- && !is_in_const_context ( cx)
110134 {
111135 let exp_ty = cx. typeck_results ( ) . expr_ty ( let_expr. init ) ;
112136 let pat_ty = cx. typeck_results ( ) . pat_ty ( let_expr. pat ) ;
113137 let mut applicability = Applicability :: MachineApplicable ;
114138
115- if is_structural_partial_eq ( cx, exp_ty, pat_ty) && !contains_type_mismatch ( cx, let_expr. pat ) {
139+ if is_structural_partial_eq ( cx, exp_ty, pat_ty, self . msrv ) && !contains_type_mismatch ( cx, let_expr. pat ) {
116140 let pat_str = match let_expr. pat . kind {
117141 PatKind :: Struct ( ..) => format ! (
118142 "({})" ,
0 commit comments