@@ -6,6 +6,7 @@ use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
6
6
use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
7
7
use rustc_lint:: LateContext ;
8
8
use rustc_middle:: hir:: map:: Map ;
9
+ use rustc_middle:: ty:: { self , TyS } ;
9
10
use rustc_span:: sym;
10
11
11
12
use super :: UNNECESSARY_FILTER_MAP ;
@@ -28,25 +29,28 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
28
29
found_mapping |= return_visitor. found_mapping ;
29
30
found_filtering |= return_visitor. found_filtering ;
30
31
31
- if !found_filtering {
32
- span_lint (
33
- cx,
34
- UNNECESSARY_FILTER_MAP ,
35
- expr. span ,
36
- "this `.filter_map` can be written more simply using `.map`" ,
37
- ) ;
38
- return ;
39
- }
40
-
41
- if !found_mapping && !mutates_arg {
42
- span_lint (
43
- cx,
44
- UNNECESSARY_FILTER_MAP ,
45
- expr. span ,
46
- "this `.filter_map` can be written more simply using `.filter`" ,
47
- ) ;
32
+ let sugg = if !found_filtering {
33
+ "map"
34
+ } else if !found_mapping && !mutates_arg {
35
+ let in_ty = cx. typeck_results ( ) . node_type ( body. params [ 0 ] . hir_id ) ;
36
+ match cx. typeck_results ( ) . expr_ty ( & body. value ) . kind ( ) {
37
+ ty:: Adt ( adt, subst)
38
+ if cx. tcx . is_diagnostic_item ( sym:: option_type, adt. did )
39
+ && TyS :: same_type ( in_ty, subst. type_at ( 0 ) ) =>
40
+ {
41
+ "filter"
42
+ } ,
43
+ _ => return ,
44
+ }
45
+ } else {
48
46
return ;
49
- }
47
+ } ;
48
+ span_lint (
49
+ cx,
50
+ UNNECESSARY_FILTER_MAP ,
51
+ expr. span ,
52
+ & format ! ( "this `.filter_map` can be written more simply using `.{}`" , sugg) ,
53
+ ) ;
50
54
}
51
55
}
52
56
0 commit comments