@@ -2,14 +2,13 @@ use super::utils::clone_or_copy_needed;
22use clippy_utils:: diagnostics:: span_lint;
33use clippy_utils:: res:: { MaybeDef , MaybeQPath , MaybeResPath , MaybeTypeckRes } ;
44use clippy_utils:: sym;
5- use clippy_utils:: ty:: is_copy;
5+ use clippy_utils:: ty:: { is_copy, option_arg_ty } ;
66use clippy_utils:: usage:: mutated_variables;
77use clippy_utils:: visitors:: { Descend , for_each_expr_without_closures} ;
88use core:: ops:: ControlFlow ;
99use rustc_hir as hir;
1010use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
1111use rustc_lint:: LateContext ;
12- use rustc_middle:: ty;
1312use rustc_span:: Symbol ;
1413
1514use super :: { UNNECESSARY_FILTER_MAP , UNNECESSARY_FIND_MAP } ;
@@ -46,9 +45,9 @@ pub(super) fn check<'tcx>(
4645 let sugg = if !found_filtering {
4746 // Check if the closure is .filter_map(|x| Some(x))
4847 if name == sym:: filter_map
49- && let hir:: ExprKind :: Call ( expr, args ) = body. value . kind
48+ && let hir:: ExprKind :: Call ( expr, [ arg ] ) = body. value . kind
5049 && expr. res ( cx) . ctor_parent ( cx) . is_lang_item ( cx, OptionSome )
51- && let hir:: ExprKind :: Path ( _) = args [ 0 ] . kind
50+ && let hir:: ExprKind :: Path ( _) = arg . kind
5251 {
5352 span_lint (
5453 cx,
@@ -64,17 +63,15 @@ pub(super) fn check<'tcx>(
6463 "map(..).next()"
6564 }
6665 } else if !found_mapping && !mutates_arg && ( !clone_or_copy_needed || is_copy ( cx, in_ty) ) {
67- match cx. typeck_results ( ) . expr_ty ( body. value ) . kind ( ) {
68- ty:: Adt ( adt, subst)
69- if cx. tcx . is_diagnostic_item ( sym:: Option , adt. did ( ) ) && in_ty == subst. type_at ( 0 ) =>
70- {
71- if name == sym:: filter_map {
72- "filter(..)"
73- } else {
74- "find(..)"
75- }
76- } ,
77- _ => return ,
66+ let ty = cx. typeck_results ( ) . expr_ty ( body. value ) ;
67+ 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(..)"
72+ }
73+ } else {
74+ return ;
7875 }
7976 } else {
8077 return ;
@@ -95,11 +92,22 @@ pub(super) fn check<'tcx>(
9592// returns (found_mapping, found_filtering)
9693fn check_expression < ' tcx > ( cx : & LateContext < ' tcx > , arg_id : hir:: HirId , expr : & ' tcx hir:: Expr < ' _ > ) -> ( bool , bool ) {
9794 match expr. kind {
95+ hir:: ExprKind :: Path ( ref path)
96+ if cx
97+ . qpath_res ( path, expr. hir_id )
98+ . ctor_parent ( cx)
99+ . is_lang_item ( cx, OptionNone ) =>
100+ {
101+ // None
102+ ( false , true )
103+ } ,
98104 hir:: ExprKind :: Call ( func, args) => {
99105 if func. res ( cx) . ctor_parent ( cx) . is_lang_item ( cx, OptionSome ) {
100106 if args[ 0 ] . res_local_id ( ) == Some ( arg_id) {
107+ // Some(arg_id)
101108 return ( false , false ) ;
102109 }
110+ // Some(not arg_id)
103111 return ( true , false ) ;
104112 }
105113 ( true , true )
@@ -109,8 +117,10 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
109117 && cx. typeck_results ( ) . expr_ty ( recv) . is_bool ( )
110118 && arg. res_local_id ( ) == Some ( arg_id)
111119 {
120+ // bool.then_some(arg_id)
112121 ( false , true )
113122 } else {
123+ // bool.then_some(not arg_id)
114124 ( true , true )
115125 }
116126 } ,
@@ -134,14 +144,6 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
134144 let else_check = check_expression ( cx, arg_id, else_arm) ;
135145 ( if_check. 0 | else_check. 0 , if_check. 1 | else_check. 1 )
136146 } ,
137- hir:: ExprKind :: Path ( ref path)
138- if cx
139- . qpath_res ( path, expr. hir_id )
140- . ctor_parent ( cx)
141- . is_lang_item ( cx, OptionNone ) =>
142- {
143- ( false , true )
144- } ,
145147 _ => ( true , true ) ,
146148 }
147149}
0 commit comments