Skip to content

Commit 3fec6f5

Browse files
committed
Improve some suggestions for filter_map_next, filter_next and map_unwrap_or lints
1 parent 2911d9c commit 3fec6f5

File tree

4 files changed

+22
-30
lines changed

4 files changed

+22
-30
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ use crate::utils::{
3232
is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath,
3333
match_trait_method, match_type, match_var, method_calls, method_chain_args, paths, remove_blocks, return_ty,
3434
single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
35-
span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth,
36-
SpanlessEq,
35+
span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth, SpanlessEq,
3736
};
3837

3938
declare_clippy_lint! {
@@ -2753,16 +2752,15 @@ fn lint_map_unwrap_or_else<'tcx>(
27532752
let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1;
27542753
let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt();
27552754
if same_span && !multiline {
2756-
span_lint_and_note(
2755+
let var_snippet = snippet(cx, map_args[0].span, "..");
2756+
span_lint_and_sugg(
27572757
cx,
27582758
MAP_UNWRAP_OR,
27592759
expr.span,
27602760
msg,
2761-
None,
2762-
&format!(
2763-
"replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`",
2764-
map_snippet, unwrap_snippet,
2765-
),
2761+
"try this",
2762+
format!("{}.map_or_else({}, {})", var_snippet, unwrap_snippet, map_snippet),
2763+
Applicability::MachineApplicable,
27662764
);
27672765
return true;
27682766
} else if same_span && multiline {
@@ -2852,14 +2850,16 @@ fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, fil
28522850
`.find(..)` instead.";
28532851
let filter_snippet = snippet(cx, filter_args[1].span, "..");
28542852
if filter_snippet.lines().count() <= 1 {
2853+
let iter_snippet = snippet(cx, filter_args[0].span, "..");
28552854
// add note if not multi-line
2856-
span_lint_and_note(
2855+
span_lint_and_sugg(
28572856
cx,
28582857
FILTER_NEXT,
28592858
expr.span,
28602859
msg,
2861-
None,
2862-
&format!("replace `filter({0}).next()` with `find({0})`", filter_snippet),
2860+
"try this",
2861+
format!("{}.find({})", iter_snippet, filter_snippet),
2862+
Applicability::MachineApplicable,
28632863
);
28642864
} else {
28652865
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<'_>,
29082908
`.find_map(..)` instead.";
29092909
let filter_snippet = snippet(cx, filter_args[1].span, "..");
29102910
if filter_snippet.lines().count() <= 1 {
2911-
span_lint_and_note(
2911+
let iter_snippet = snippet(cx, filter_args[0].span, "..");
2912+
span_lint_and_sugg(
29122913
cx,
29132914
FILTER_MAP_NEXT,
29142915
expr.span,
29152916
msg,
2916-
None,
2917-
&format!("replace `filter_map({0}).next()` with `find_map({0})`", filter_snippet),
2917+
"try this",
2918+
format!("{}.find_map({})", iter_snippet, filter_snippet),
2919+
Applicability::MachineApplicable,
29182920
);
29192921
} else {
29202922
span_lint(cx, FILTER_MAP_NEXT, expr.span, msg);

tests/ui/filter_map_next.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly
22
--> $DIR/filter_map_next.rs:6:32
33
|
44
LL | let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())`
66
|
77
= note: `-D clippy::filter-map-next` implied by `-D warnings`
8-
= note: replace `filter_map(|s| s.parse().ok()).next()` with `find_map(|s| s.parse().ok())`
98

109
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead.
1110
--> $DIR/filter_map_next.rs:10:26

tests/ui/map_unwrap_or.stderr

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ LL | let _ = opt.map(|x| x + 1)
109109
| _____________^
110110
LL | | // Should lint even though this call is on a separate line.
111111
LL | | .unwrap_or_else(|| 0);
112-
| |_____________________________^
113-
|
114-
= note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `map_or_else(|| 0, |x| x + 1)`
112+
| |_____________________________^ help: try this: `opt.map_or_else(|| 0, |x| x + 1)`
115113

116114
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
117115
--> $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
137135
--> $DIR/map_unwrap_or.rs:88:13
138136
|
139137
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0); // should lint even though this call is on a separate line
140-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
141-
|
142-
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
138+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
143139

144140
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
145141
--> $DIR/map_unwrap_or.rs:90:13
146142
|
147143
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0);
148-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149-
|
150-
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
144+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
151145

152146
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
153147
--> $DIR/map_unwrap_or.rs:91:13
154148
|
155149
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|e| 0);
156-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
157-
|
158-
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `map_or_else(|e| 0, |x| x + 1)`
150+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|e| 0, |x| x + 1)`
159151

160152
error: aborting due to 13 previous errors
161153

tests/ui/methods.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ error: called `filter(..).next()` on an `Iterator`. This is more succinctly expr
1212
--> $DIR/methods.rs:126:13
1313
|
1414
LL | let _ = v.iter().filter(|&x| *x < 0).next();
15-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `v.iter().find(|&x| *x < 0)`
1616
|
1717
= note: `-D clippy::filter-next` implied by `-D warnings`
18-
= note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)`
1918

2019
error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead.
2120
--> $DIR/methods.rs:129:13

0 commit comments

Comments
 (0)