Skip to content

Commit 56c6a8b

Browse files
committed
Split arg/method checking into its own function
1 parent 1032009 commit 56c6a8b

File tree

1 file changed

+37
-46
lines changed

1 file changed

+37
-46
lines changed

clippy_lints/src/lines_filter_map_ok.rs

+37-46
Original file line numberDiff line numberDiff line change
@@ -63,55 +63,46 @@ impl LateLintPass<'_> for LinesFilterMapOk {
6363
is_trait_method(cx, expr, sym::Iterator) &&
6464
let fm_method_str = fm_method.ident.as_str() &&
6565
matches!(fm_method_str, "filter_map" | "flat_map" | "flatten") &&
66-
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines)
66+
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) &&
67+
should_lint(cx, fm_args, fm_method_str)
6768
{
68-
let lint = match fm_args {
69-
[] => fm_method_str == "flatten",
70-
[fm_arg] => {
71-
match &fm_arg.kind {
72-
// Detect `Result::ok`
73-
ExprKind::Path(qpath) =>
74-
cx.qpath_res(qpath, fm_arg.hir_id).opt_def_id().map(|did|
75-
match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)).unwrap_or_default(),
76-
// Detect `|x| x.ok()`
77-
ExprKind::Closure(Closure { body, .. }) =>
78-
if let Body { params: [param], value, .. } = cx.tcx.hir().body(*body) &&
79-
let ExprKind::MethodCall(method, receiver, [], _) = value.kind &&
80-
path_to_local_id(receiver, param.pat.hir_id) &&
81-
let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id)
82-
{
83-
is_diag_item_method(cx, method_did, sym::Result) && method.ident.as_str() == "ok"
84-
} else {
85-
false
86-
},
87-
_ => false,
88-
}
89-
}
90-
_ => false,
91-
};
69+
span_lint_and_then(cx,
70+
LINES_FILTER_MAP_OK,
71+
fm_span,
72+
&format!("`{}()` will run forever if the iterator repeatedly produces an `Err`", fm_method.ident),
73+
|diag| {
74+
diag.span_note(
75+
fm_receiver.span,
76+
"this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error");
77+
diag.span_suggestion(fm_span, "replace with", "map_while(Result::ok)", Applicability::MaybeIncorrect);
78+
});
79+
}
80+
}
81+
}
9282

93-
if lint {
94-
span_lint_and_then(
95-
cx,
96-
LINES_FILTER_MAP_OK,
97-
fm_span,
98-
&format!(
99-
"`{}()` will run forever if the iterator repeatedly produces an `Err`",
100-
fm_method.ident
101-
),
102-
|diag| {
103-
diag.span_note(
104-
fm_receiver.span,
105-
"this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error");
106-
diag.span_suggestion(
107-
fm_span,
108-
"replace with",
109-
"map_while(Result::ok)",
110-
Applicability::MaybeIncorrect,
111-
);
83+
fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> bool {
84+
match args {
85+
[] => method_str == "flatten",
86+
[fm_arg] => {
87+
match &fm_arg.kind {
88+
// Detect `Result::ok`
89+
ExprKind::Path(qpath) =>
90+
cx.qpath_res(qpath, fm_arg.hir_id).opt_def_id().map(|did|
91+
match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)).unwrap_or_default(),
92+
// Detect `|x| x.ok()`
93+
ExprKind::Closure(Closure { body, .. }) =>
94+
if let Body { params: [param], value, .. } = cx.tcx.hir().body(*body) &&
95+
let ExprKind::MethodCall(method, receiver, [], _) = value.kind &&
96+
path_to_local_id(receiver, param.pat.hir_id) &&
97+
let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id)
98+
{
99+
is_diag_item_method(cx, method_did, sym::Result) && method.ident.as_str() == "ok"
100+
} else {
101+
false
112102
},
113-
);
103+
_ => false,
114104
}
115-
}
105+
},
106+
_ => false,
116107
}
117108
}

0 commit comments

Comments
 (0)