Improve some suggestions for filter_map_next, filter_next and map_unwrap_or lints

This commit is contained in:
ThibsG 2020-10-19 18:47:02 +02:00
parent 2911d9c7de
commit 3fec6f568d
4 changed files with 22 additions and 30 deletions

View file

@ -32,8 +32,7 @@ use crate::utils::{
is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath,
match_trait_method, match_type, match_var, method_calls, method_chain_args, paths, remove_blocks, return_ty,
single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth,
SpanlessEq,
span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth, SpanlessEq,
};
declare_clippy_lint! {
@ -2753,16 +2752,15 @@ fn lint_map_unwrap_or_else<'tcx>(
let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1;
let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt();
if same_span && !multiline {
span_lint_and_note(
let var_snippet = snippet(cx, map_args[0].span, "..");
span_lint_and_sugg(
cx,
MAP_UNWRAP_OR,
expr.span,
msg,
None,
&format!(
"replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`",
map_snippet, unwrap_snippet,
),
"try this",
format!("{}.map_or_else({}, {})", var_snippet, unwrap_snippet, map_snippet),
Applicability::MachineApplicable,
);
return true;
} else if same_span && multiline {
@ -2852,14 +2850,16 @@ fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, fil
`.find(..)` instead.";
let filter_snippet = snippet(cx, filter_args[1].span, "..");
if filter_snippet.lines().count() <= 1 {
let iter_snippet = snippet(cx, filter_args[0].span, "..");
// add note if not multi-line
span_lint_and_note(
span_lint_and_sugg(
cx,
FILTER_NEXT,
expr.span,
msg,
None,
&format!("replace `filter({0}).next()` with `find({0})`", filter_snippet),
"try this",
format!("{}.find({})", iter_snippet, filter_snippet),
Applicability::MachineApplicable,
);
} else {
span_lint(cx, FILTER_NEXT, expr.span, msg);
@ -2908,13 +2908,15 @@ fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>,
`.find_map(..)` instead.";
let filter_snippet = snippet(cx, filter_args[1].span, "..");
if filter_snippet.lines().count() <= 1 {
span_lint_and_note(
let iter_snippet = snippet(cx, filter_args[0].span, "..");
span_lint_and_sugg(
cx,
FILTER_MAP_NEXT,
expr.span,
msg,
None,
&format!("replace `filter_map({0}).next()` with `find_map({0})`", filter_snippet),
"try this",
format!("{}.find_map({})", iter_snippet, filter_snippet),
Applicability::MachineApplicable,
);
} else {
span_lint(cx, FILTER_MAP_NEXT, expr.span, msg);

View file

@ -2,10 +2,9 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly
--> $DIR/filter_map_next.rs:6:32
|
LL | let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())`
|
= note: `-D clippy::filter-map-next` implied by `-D warnings`
= note: replace `filter_map(|s| s.parse().ok()).next()` with `find_map(|s| s.parse().ok())`
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead.
--> $DIR/filter_map_next.rs:10:26

View file

@ -109,9 +109,7 @@ LL | let _ = opt.map(|x| x + 1)
| _____________^
LL | | // Should lint even though this call is on a separate line.
LL | | .unwrap_or_else(|| 0);
| |_____________________________^
|
= note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `map_or_else(|| 0, |x| x + 1)`
| |_____________________________^ help: try this: `opt.map_or_else(|| 0, |x| x + 1)`
error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead
--> $DIR/map_unwrap_or.rs:55:13
@ -137,25 +135,19 @@ error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be do
--> $DIR/map_unwrap_or.rs:88:13
|
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0); // should lint even though this call is on a separate line
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead
--> $DIR/map_unwrap_or.rs:90:13
|
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead
--> $DIR/map_unwrap_or.rs:91:13
|
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
error: aborting due to 13 previous errors

View file

@ -12,10 +12,9 @@ error: called `filter(..).next()` on an `Iterator`. This is more succinctly expr
--> $DIR/methods.rs:126:13
|
LL | let _ = v.iter().filter(|&x| *x < 0).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `v.iter().find(|&x| *x < 0)`
|
= note: `-D clippy::filter-next` implied by `-D warnings`
= note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)`
error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead.
--> $DIR/methods.rs:129:13