Skip to content

Commit d66d373

Browse files
committed
Fix unnecessary_filter_map false positive
1 parent a8f28b6 commit d66d373

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

clippy_lints/src/methods/unnecessary_filter_map.rs

+22-18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
66
use rustc_hir::LangItem::{OptionNone, OptionSome};
77
use rustc_lint::LateContext;
88
use rustc_middle::hir::map::Map;
9+
use rustc_middle::ty::{self, TyS};
910
use rustc_span::sym;
1011

1112
use 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

tests/ui/unnecessary_filter_map.rs

+4
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ fn main() {
1515

1616
let _ = (0..4).filter_map(i32::checked_abs);
1717
}
18+
19+
fn filter_map_none_changes_item_type() -> impl Iterator<Item = bool> {
20+
"".chars().filter_map(|_| None)
21+
}

0 commit comments

Comments
 (0)