@@ -6,6 +6,7 @@ use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
66use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
77use rustc_lint:: LateContext ;
88use rustc_middle:: hir:: map:: Map ;
9+ use rustc_middle:: ty:: { self , TyS } ;
910use rustc_span:: sym;
1011
1112use super :: UNNECESSARY_FILTER_MAP ;
@@ -28,25 +29,28 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
2829 found_mapping |= return_visitor. found_mapping ;
2930 found_filtering |= return_visitor. found_filtering ;
3031
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 {
4846 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+ ) ;
5054 }
5155}
5256
0 commit comments