@@ -223,6 +223,26 @@ declare_clippy_lint! {
223223 "a wildcard enum match arm using `_`"
224224}
225225
226+ declare_clippy_lint ! {
227+ /// **What it does:** Checks for wildcard pattern used with others patterns in same match arm.
228+ ///
229+ /// **Why is this bad?** Wildcard pattern already covers any other pattern as it will match anyway.
230+ /// It makes the code less readable, especially to spot wildcard pattern use in match arm.
231+ ///
232+ /// **Known problems:** None.
233+ ///
234+ /// **Example:**
235+ /// ```rust
236+ /// match "foo" {
237+ /// "a" => {},
238+ /// "bar" | _ => {},
239+ /// }
240+ /// ```
241+ pub PATS_WITH_WILD_MATCH_ARM ,
242+ restriction,
243+ "a wildcard pattern used with others patterns in same match arm"
244+ }
245+
226246declare_lint_pass ! ( Matches => [
227247 SINGLE_MATCH ,
228248 MATCH_REF_PATS ,
@@ -231,7 +251,8 @@ declare_lint_pass!(Matches => [
231251 MATCH_OVERLAPPING_ARM ,
232252 MATCH_WILD_ERR_ARM ,
233253 MATCH_AS_REF ,
234- WILDCARD_ENUM_MATCH_ARM
254+ WILDCARD_ENUM_MATCH_ARM ,
255+ PATS_WITH_WILD_MATCH_ARM
235256] ) ;
236257
237258impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Matches {
@@ -246,6 +267,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
246267 check_wild_err_arm ( cx, ex, arms) ;
247268 check_wild_enum_match ( cx, ex, arms) ;
248269 check_match_as_ref ( cx, ex, arms, expr) ;
270+ check_pats_wild_match ( cx, ex, arms, expr) ;
249271 }
250272 if let ExprKind :: Match ( ref ex, ref arms, _) = expr. kind {
251273 check_match_ref_pats ( cx, ex, arms, expr) ;
@@ -664,6 +686,25 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
664686 }
665687}
666688
689+ fn check_pats_wild_match ( cx : & LateContext < ' _ , ' _ > , _ex : & Expr , arms : & [ Arm ] , _expr : & Expr ) {
690+ for arm in arms {
691+ if let PatKind :: Or ( ref fields) = arm. pat . kind {
692+ // look for multiple fields where one at least matches Wild pattern
693+ if fields. len ( ) > 1 && fields. into_iter ( ) . any ( |pat| is_wild ( pat) ) {
694+ span_lint_and_sugg (
695+ cx,
696+ PATS_WITH_WILD_MATCH_ARM ,
697+ arm. pat . span ,
698+ "wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only" ,
699+ "try this" ,
700+ "_" . to_string ( ) ,
701+ Applicability :: MachineApplicable ,
702+ )
703+ }
704+ }
705+ }
706+ }
707+
667708/// Gets all arms that are unbounded `PatRange`s.
668709fn all_ranges < ' a , ' tcx > ( cx : & LateContext < ' a , ' tcx > , arms : & ' tcx [ Arm ] ) -> Vec < SpannedRange < Constant > > {
669710 arms. iter ( )
0 commit comments