@@ -9,16 +9,11 @@ use core::ops::ControlFlow;
99use rustc_hir as hir;
1010use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
1111use rustc_lint:: LateContext ;
12- use rustc_span :: Symbol ;
12+ use std :: fmt :: Display ;
1313
1414use super :: { UNNECESSARY_FILTER_MAP , UNNECESSARY_FIND_MAP } ;
1515
16- pub ( super ) fn check < ' tcx > (
17- cx : & LateContext < ' tcx > ,
18- expr : & ' tcx hir:: Expr < ' tcx > ,
19- arg : & ' tcx hir:: Expr < ' tcx > ,
20- name : Symbol ,
21- ) {
16+ pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' tcx > , arg : & ' tcx hir:: Expr < ' tcx > , kind : Kind ) {
2217 if !cx. ty_based_def ( expr) . opt_parent ( cx) . is_diag_item ( cx, sym:: Iterator ) {
2318 return ;
2419 }
@@ -44,7 +39,7 @@ pub(super) fn check<'tcx>(
4439 let in_ty = cx. typeck_results ( ) . node_type ( body. params [ 0 ] . hir_id ) ;
4540 let sugg = if !found_filtering {
4641 // Check if the closure is .filter_map(|x| Some(x))
47- if name == sym :: filter_map
42+ if kind . is_filter_map ( )
4843 && let hir:: ExprKind :: Call ( expr, [ arg] ) = body. value . kind
4944 && expr. res ( cx) . ctor_parent ( cx) . is_lang_item ( cx, OptionSome )
5045 && let hir:: ExprKind :: Path ( _) = arg. kind
@@ -57,18 +52,16 @@ pub(super) fn check<'tcx>(
5752 ) ;
5853 return ;
5954 }
60- if name == sym:: filter_map {
61- "map(..)"
62- } else {
63- "map(..).next()"
55+ match kind {
56+ Kind :: FilterMap => "map(..)" ,
57+ Kind :: FindMap => "map(..).next()" ,
6458 }
6559 } else if !found_mapping && !mutates_arg && ( !clone_or_copy_needed || is_copy ( cx, in_ty) ) {
6660 let ty = cx. typeck_results ( ) . expr_ty ( body. value ) ;
6761 if option_arg_ty ( cx, ty) . is_some_and ( |t| t == in_ty) {
68- if name == sym:: filter_map {
69- "filter(..)"
70- } else {
71- "find(..)"
62+ match kind {
63+ Kind :: FilterMap => "filter(..)" ,
64+ Kind :: FindMap => "find(..)" ,
7265 }
7366 } else {
7467 return ;
@@ -78,17 +71,37 @@ pub(super) fn check<'tcx>(
7871 } ;
7972 span_lint (
8073 cx,
81- if name == sym:: filter_map {
82- UNNECESSARY_FILTER_MAP
83- } else {
84- UNNECESSARY_FIND_MAP
74+ match kind {
75+ Kind :: FilterMap => UNNECESSARY_FILTER_MAP ,
76+ Kind :: FindMap => UNNECESSARY_FIND_MAP ,
8577 } ,
8678 expr. span ,
87- format ! ( "this `.{name }(..)` can be written more simply using `.{sugg}`" ) ,
79+ format ! ( "this `.{kind }(..)` can be written more simply using `.{sugg}`" ) ,
8880 ) ;
8981 }
9082}
9183
84+ #[ derive( Clone , Copy ) ]
85+ pub ( super ) enum Kind {
86+ FilterMap ,
87+ FindMap ,
88+ }
89+
90+ impl Kind {
91+ fn is_filter_map ( self ) -> bool {
92+ matches ! ( self , Self :: FilterMap )
93+ }
94+ }
95+
96+ impl Display for Kind {
97+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
98+ match self {
99+ Self :: FilterMap => f. write_str ( "filter_map" ) ,
100+ Self :: FindMap => f. write_str ( "find_map" ) ,
101+ }
102+ }
103+ }
104+
92105// returns (found_mapping, found_filtering)
93106fn check_expression < ' tcx > ( cx : & LateContext < ' tcx > , arg_id : hir:: HirId , expr : & ' tcx hir:: Expr < ' _ > ) -> ( bool , bool ) {
94107 match expr. kind {
0 commit comments