Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4b1ac31

Browse files
Added MSRV and more tests, improved wording
1 parent 25b9ca3 commit 4b1ac31

File tree

8 files changed

+88
-22
lines changed

8 files changed

+88
-22
lines changed

clippy_config/src/msrvs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ msrv_aliases! {
4141
1,35,0 { OPTION_COPIED, RANGE_CONTAINS }
4242
1,34,0 { TRY_FROM }
4343
1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
44+
1,29,0 { ITER_FLATTEN }
4445
1,28,0 { FROM_BOOL }
4546
1,27,0 { ITERATOR_TRY_FOLD }
4647
1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }

clippy_lints/src/methods/iter_filter.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use rustc_lint::LateContext;
1+
use rustc_lint::{LateContext, LintContext};
22

33
use super::{ITER_FILTER_IS_OK, ITER_FILTER_IS_SOME};
44

55
use clippy_utils::diagnostics::span_lint_and_sugg;
66
use clippy_utils::source::{indent_of, reindent_multiline};
7-
use clippy_utils::{is_trait_method, peel_blocks};
7+
use clippy_utils::{is_trait_method, peel_blocks, span_contains_comment};
88
use rustc_errors::Applicability;
99
use rustc_hir as hir;
1010
use rustc_hir::def::Res;
@@ -54,26 +54,40 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_arg: &hir
5454
let is_iterator = is_trait_method(cx, expr, sym::Iterator);
5555
let parent_is_not_map = !parent_is_map(cx, expr);
5656

57-
if is_iterator && parent_is_not_map && is_method(cx, filter_arg, sym!(is_some)) {
57+
if is_iterator
58+
&& parent_is_not_map
59+
&& is_method(cx, filter_arg, sym!(is_some))
60+
&& !span_contains_comment(
61+
cx.sess().source_map(),
62+
filter_span.with_hi(expr.span.hi())
63+
)
64+
{
5865
span_lint_and_sugg(
5966
cx,
6067
ITER_FILTER_IS_SOME,
6168
filter_span.with_hi(expr.span.hi()),
6269
"`filter` for `is_some` on iterator over `Option`",
6370
"consider using `flatten` instead",
6471
reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, filter_span)).into_owned(),
65-
Applicability::MaybeIncorrect,
72+
Applicability::HasPlaceholders,
6673
);
6774
}
68-
if is_iterator && parent_is_not_map && is_method(cx, filter_arg, sym!(is_ok)) {
75+
if is_iterator
76+
&& parent_is_not_map
77+
&& is_method(cx, filter_arg, sym!(is_ok))
78+
&& !span_contains_comment(
79+
cx.sess().source_map(),
80+
filter_span.with_hi(expr.span.hi())
81+
)
82+
{
6983
span_lint_and_sugg(
7084
cx,
7185
ITER_FILTER_IS_OK,
7286
filter_span.with_hi(expr.span.hi()),
7387
"`filter` for `is_ok` on iterator over `Result`s",
7488
"consider using `flatten` instead",
7589
reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, filter_span)).into_owned(),
76-
Applicability::MaybeIncorrect,
90+
Applicability::HasPlaceholders,
7791
);
7892
}
7993
}

clippy_lints/src/methods/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3779,8 +3779,8 @@ declare_clippy_lint! {
37793779

37803780
declare_clippy_lint! {
37813781
/// ### What it does
3782-
/// Checks for usage of `.filter(Optional::is_some)` that may be replaced with a `.flatten()` call.
3783-
/// This lint is potentially incorrect as it affects the type of follow-up calls.
3782+
/// Checks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call.
3783+
/// This lint will require additional changes to the follow-up calls as it appects the type.
37843784
///
37853785
/// ### Why is this bad?
37863786
/// This pattern is often followed by manual unwrapping of the `Option`. The simplification
@@ -3799,14 +3799,14 @@ declare_clippy_lint! {
37993799
/// ```
38003800
#[clippy::version = "1.76.0"]
38013801
pub ITER_FILTER_IS_SOME,
3802-
complexity,
3802+
pedantic,
38033803
"filtering an iterator over `Option`s for `Some` can be achieved with `flatten`"
38043804
}
38053805

38063806
declare_clippy_lint! {
38073807
/// ### What it does
38083808
/// Checks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call.
3809-
/// This lint is potentially incorrect as it affects the type of follow-up calls.
3809+
/// This lint will require additional changes to the follow-up calls as it appects the type.
38103810
///
38113811
/// ### Why is this bad?
38123812
/// This pattern is often followed by manual unwrapping of `Result`. The simplification
@@ -3825,7 +3825,7 @@ declare_clippy_lint! {
38253825
/// ```
38263826
#[clippy::version = "1.76.0"]
38273827
pub ITER_FILTER_IS_OK,
3828-
complexity,
3828+
pedantic,
38293829
"filtering an iterator over `Result`s for `Ok` can be achieved with `flatten`"
38303830
}
38313831

@@ -4324,8 +4324,11 @@ impl Methods {
43244324
false,
43254325
);
43264326
}
4327+
if self.msrv.meets(msrvs::ITER_FLATTEN) {
43274328

4328-
iter_filter::check(cx, expr, arg, span);
4329+
// use the sourcemap to get the span of the closure
4330+
iter_filter::check(cx, expr, arg, span);
4331+
}
43294332
},
43304333
("find", [arg]) => {
43314334
if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {

tests/ui/iter_filter_is_ok.fixed

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,18 @@ fn main() {
55
//~^ HELP: consider using `flatten` instead
66
let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();
77
//~^ HELP: consider using `flatten` instead
8+
9+
// Don't lint below
10+
let mut counter = 0;
11+
let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {
12+
counter += 1;
13+
o.is_ok()
14+
});
15+
let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {
16+
// Roses are red,
17+
// Violets are blue,
18+
// `Err` is not an `Option`,
19+
// and this doesn't ryme
20+
o.is_ok()
21+
});
822
}

tests/ui/iter_filter_is_ok.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,18 @@ fn main() {
55
//~^ HELP: consider using `flatten` instead
66
let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| a.is_ok());
77
//~^ HELP: consider using `flatten` instead
8+
9+
// Don't lint below
10+
let mut counter = 0;
11+
let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {
12+
counter += 1;
13+
o.is_ok()
14+
});
15+
let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {
16+
// Roses are red,
17+
// Violets are blue,
18+
// `Err` is not an `Option`,
19+
// and this doesn't ryme
20+
o.is_ok()
21+
});
822
}

tests/ui/iter_filter_is_some.fixed

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
#![warn(clippy::iter_filter_is_some)]
22

3-
fn odds_out(x: i32) -> Option<i32> {
4-
if x % 2 == 0 { Some(x) } else { None }
5-
}
6-
73
fn main() {
84
let _ = vec![Some(1)].into_iter().flatten();
95
//~^ HELP: consider using `flatten` instead
106
let _ = vec![Some(1)].into_iter().flatten();
117
//~^ HELP: consider using `flatten` instead
8+
9+
// Don't lint below
10+
let mut counter = 0;
11+
let _ = vec![Some(1)].into_iter().filter(|o| {
12+
counter += 1;
13+
o.is_some()
14+
});
15+
let _ = vec![Some(1)].into_iter().filter(|o| {
16+
// Roses are red,
17+
// Violets are blue,
18+
// `Err` is not an `Option`,
19+
// and this doesn't ryme
20+
o.is_some()
21+
});
1222
}

tests/ui/iter_filter_is_some.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
#![warn(clippy::iter_filter_is_some)]
22

3-
fn odds_out(x: i32) -> Option<i32> {
4-
if x % 2 == 0 { Some(x) } else { None }
5-
}
6-
73
fn main() {
84
let _ = vec![Some(1)].into_iter().filter(Option::is_some);
95
//~^ HELP: consider using `flatten` instead
106
let _ = vec![Some(1)].into_iter().filter(|o| o.is_some());
117
//~^ HELP: consider using `flatten` instead
8+
9+
// Don't lint below
10+
let mut counter = 0;
11+
let _ = vec![Some(1)].into_iter().filter(|o| {
12+
counter += 1;
13+
o.is_some()
14+
});
15+
let _ = vec![Some(1)].into_iter().filter(|o| {
16+
// Roses are red,
17+
// Violets are blue,
18+
// `Err` is not an `Option`,
19+
// and this doesn't ryme
20+
o.is_some()
21+
});
1222
}

tests/ui/iter_filter_is_some.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `filter` for `is_some` on iterator over `Option`
2-
--> $DIR/iter_filter_is_some.rs:8:39
2+
--> $DIR/iter_filter_is_some.rs:4:39
33
|
44
LL | let _ = vec![Some(1)].into_iter().filter(Option::is_some);
55
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
@@ -8,7 +8,7 @@ LL | let _ = vec![Some(1)].into_iter().filter(Option::is_some);
88
= help: to override `-D warnings` add `#[allow(clippy::iter_filter_is_some)]`
99

1010
error: `filter` for `is_some` on iterator over `Option`
11-
--> $DIR/iter_filter_is_some.rs:10:39
11+
--> $DIR/iter_filter_is_some.rs:6:39
1212
|
1313
LL | let _ = vec![Some(1)].into_iter().filter(|o| o.is_some());
1414
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`

0 commit comments

Comments
 (0)