@@ -9,9 +9,11 @@ use rustc_hir::{
9
9
} ;
10
10
use rustc_lint:: { LateContext , LateLintPass , Lint } ;
11
11
use 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 } ;
13
13
use rustc_span:: Span ;
14
14
15
+ use crate :: utils:: conf:: EquatablePatternLevel ;
16
+
15
17
declare_clippy_lint ! {
16
18
/// ### What it does
17
19
/// Checks for `if let <pat> = <expr>` (and `while let` and similars) that can be expressed
@@ -64,7 +66,17 @@ declare_clippy_lint! {
64
66
"using `matches!` instead of equality"
65
67
}
66
68
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 ] ) ;
68
80
69
81
fn equatable_pattern ( cx : & LateContext < ' _ > , pat : & Pat < ' _ > ) -> bool {
70
82
fn array_rec ( cx : & LateContext < ' _ > , pats : & [ Pat < ' _ > ] ) -> bool {
@@ -179,21 +191,30 @@ fn pat_to_string(cx: &LateContext<'tcx>, app: &mut Applicability, pat: &Pat<'_>,
179
191
Some ( r)
180
192
}
181
193
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
+ ) {
183
210
if_chain ! {
184
211
if equatable_pattern( cx, pat) ;
212
+ if level_contains( level, pat) ;
185
213
let exp_ty = cx. typeck_results( ) . expr_ty( exp) ;
186
214
if is_partial_eq( cx, exp_ty, exp_ty) ;
187
215
let mut app = Applicability :: MachineApplicable ;
188
216
if let Some ( pat_str) = pat_to_string( cx, & mut app, pat, exp_ty) ;
189
217
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
- };*/
197
218
let exp_str = snippet_with_applicability( cx, exp. span, ".." , & mut app) ;
198
219
span_lint_and_sugg(
199
220
cx,
@@ -215,15 +236,15 @@ fn emit_lint(cx: &LateContext<'tcx>, pat: &Pat<'_>, exp: &Expr<'_>, span: Span,
215
236
impl < ' tcx > LateLintPass < ' tcx > for PatternEquality {
216
237
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
217
238
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 ) ;
219
240
}
220
241
if let Some ( MatchesExpn {
221
242
call_site,
222
243
arm : Arm { pat, guard : None , .. } ,
223
244
exp,
224
245
} ) = MatchesExpn :: parse ( expr)
225
246
{
226
- emit_lint ( cx, pat, exp, call_site, EQUATABLE_MATCHES ) ;
247
+ emit_lint ( cx, pat, exp, call_site, EQUATABLE_MATCHES , self . level ) ;
227
248
}
228
249
}
229
250
}
0 commit comments