@@ -9,9 +9,11 @@ use rustc_hir::{
99} ;
1010use rustc_lint:: { LateContext , LateLintPass , Lint } ;
1111use rustc_middle:: ty:: { Adt , Ty } ;
12- use rustc_session:: { declare_lint_pass , declare_tool_lint } ;
12+ use rustc_session:: { declare_tool_lint , impl_lint_pass } ;
1313use rustc_span:: Span ;
1414
15+ use crate :: utils:: conf:: EquatablePatternLevel ;
16+
1517declare_clippy_lint ! {
1618 /// ### What it does
1719 /// Checks for `if let <pat> = <expr>` (and `while let` and similars) that can be expressed
@@ -64,7 +66,17 @@ declare_clippy_lint! {
6466 "using `matches!` instead of equality"
6567}
6668
67- declare_lint_pass ! ( PatternEquality => [ EQUATABLE_IF_LET , EQUATABLE_MATCHES ] ) ;
69+ pub struct PatternEquality {
70+ level : EquatablePatternLevel ,
71+ }
72+
73+ impl PatternEquality {
74+ pub fn new ( level : EquatablePatternLevel ) -> PatternEquality {
75+ PatternEquality { level }
76+ }
77+ }
78+
79+ impl_lint_pass ! ( PatternEquality => [ EQUATABLE_IF_LET , EQUATABLE_MATCHES ] ) ;
6880
6981fn equatable_pattern ( cx : & LateContext < ' _ > , pat : & Pat < ' _ > ) -> bool {
7082 fn array_rec ( cx : & LateContext < ' _ > , pats : & [ Pat < ' _ > ] ) -> bool {
@@ -179,21 +191,30 @@ fn pat_to_string(cx: &LateContext<'tcx>, app: &mut Applicability, pat: &Pat<'_>,
179191 Some ( r)
180192}
181193
182- fn emit_lint ( cx : & LateContext < ' tcx > , pat : & Pat < ' _ > , exp : & Expr < ' _ > , span : Span , lint : & ' static Lint ) {
194+ fn level_contains ( level : EquatablePatternLevel , pat : & Pat < ' _ > ) -> bool {
195+ match level {
196+ EquatablePatternLevel :: Primitive => matches ! ( pat. kind, PatKind :: Lit ( _) ) ,
197+ EquatablePatternLevel :: Simple => matches ! ( pat. kind, PatKind :: Lit ( _) | PatKind :: Path ( _) ) ,
198+ EquatablePatternLevel :: All => true ,
199+ }
200+ }
201+
202+ fn emit_lint (
203+ cx : & LateContext < ' tcx > ,
204+ pat : & Pat < ' _ > ,
205+ exp : & Expr < ' _ > ,
206+ span : Span ,
207+ lint : & ' static Lint ,
208+ level : EquatablePatternLevel ,
209+ ) {
183210 if_chain ! {
184211 if equatable_pattern( cx, pat) ;
212+ if level_contains( level, pat) ;
185213 let exp_ty = cx. typeck_results( ) . expr_ty( exp) ;
186214 if is_partial_eq( cx, exp_ty, exp_ty) ;
187215 let mut app = Applicability :: MachineApplicable ;
188216 if let Some ( pat_str) = pat_to_string( cx, & mut app, pat, exp_ty) ;
189217 then {
190- /*let pat_str = match pat.kind {
191- PatKind::Struct(..) => format!(
192- "({})",
193- snippet_with_applicability(cx, pat.span, "..", &mut applicability),
194- ),
195- _ => snippet_with_applicability(cx, pat.span, "..", &mut applicability).to_string(),
196- };*/
197218 let exp_str = snippet_with_applicability( cx, exp. span, ".." , & mut app) ;
198219 span_lint_and_sugg(
199220 cx,
@@ -215,15 +236,15 @@ fn emit_lint(cx: &LateContext<'tcx>, pat: &Pat<'_>, exp: &Expr<'_>, span: Span,
215236impl < ' tcx > LateLintPass < ' tcx > for PatternEquality {
216237 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
217238 if let ExprKind :: Let ( pat, exp, _) = expr. kind {
218- emit_lint ( cx, pat, exp, expr. span , EQUATABLE_IF_LET ) ;
239+ emit_lint ( cx, pat, exp, expr. span , EQUATABLE_IF_LET , self . level ) ;
219240 }
220241 if let Some ( MatchesExpn {
221242 call_site,
222243 arm : Arm { pat, guard : None , .. } ,
223244 exp,
224245 } ) = MatchesExpn :: parse ( expr)
225246 {
226- emit_lint ( cx, pat, exp, call_site, EQUATABLE_MATCHES ) ;
247+ emit_lint ( cx, pat, exp, call_site, EQUATABLE_MATCHES , self . level ) ;
227248 }
228249 }
229250}
0 commit comments