Skip to content

Suggest flatten over filter(Option::is_some) #11843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
flip1995 opened this issue Nov 20, 2023 · 8 comments · Fixed by #12004
Closed

Suggest flatten over filter(Option::is_some) #11843

flip1995 opened this issue Nov 20, 2023 · 8 comments · Fixed by #12004
Assignees
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group

Comments

@flip1995
Copy link
Member

flip1995 commented Nov 20, 2023

What it does

Checks for usage of filter(Option::is_some) or filter(Result::is_ok) on an Iterator.

This is more succinctly written with just flatten().

Careful: The suggestion must be MaybeIncorrect, as this changes the type of the iterator from Item = Option<T> to Item = T.

good-first-issue instructions: This lint should be quite easy to add as another clippy_lints/src/methods/ lint. All of the parts required to check for this should already be there and can be reused.

Advantage

  • Shorter code
  • Potentially more readable code in following methods in the iterator chain:
    .filter(Option::is_some).map(|x| /*some code*/ x.unwrap() /*some code*/)
    // becomes
    .flatten().map(|x| /*some code*/ x /*some code*/)

Drawbacks

Changes the type of the iterator chain. This will lead to more refactorings required down the chain. But I think in most cases this will benefit the code complexity overall.

Example

v.into_iter().filter(Option::is_some);
v.into_iter().filter(Result::is_ok);

Could be written as:

v.into_iter().flatten();

Playground

@flip1995 flip1995 added good-first-issue These issues are a good way to get started with Clippy A-lint Area: New lints L-complexity Lint: Belongs in the complexity lint group labels Nov 20, 2023
@PartiallyUntyped
Copy link
Contributor

PartiallyUntyped commented Nov 20, 2023

@rustbot claim

@rustbot

This comment was marked as resolved.

@y21
Copy link
Member

y21 commented Nov 20, 2023

🤔 This almost exists as option_filter_map, but that only lints if there's a .map(Option::unwrap) to avoid the change of types

@PartiallyUntyped
Copy link
Contributor

Should I extend and/or possibly rename?

@y21
Copy link
Member

y21 commented Nov 20, 2023

IMO it could make sense to have this as a new lint, given that this changes types of iterator chains and may not be as applicable as option_filter_map (which should always work in any case without refactoring). But if it becomes a new lint, then it should check that the parent expr of .filter() isn't a call to .map(), so as to avoid linting twice on the same expression but with different fixes. Renaming a lint also requires deprecating the old name.
Maybe others have a different opinion on this though

@PartiallyUntyped
Copy link
Contributor

@y21 maybe I am missing something but there doesn't seem to be a result_filter_map to capture the mirror case.

@PartiallyUntyped
Copy link
Contributor

How do you think this should be tackled in light of the missing mirror?

Maybe I can add both the mirror and this?

@flip1995
Copy link
Member Author

IMO it does make sense to add a mirror for the option_filter_map. Those 2 things should be split into 2 PRs though.

bors added a commit that referenced this issue Dec 26, 2023
New lints `iter_filter_is_some` and `iter_filter_is_ok`

Adds a pair of lints that check for cases of an iterator over `Result` and `Option` followed by `filter` without being followed by `map` as that is covered already by a different, specialized lint.

Fixes #11843

PS, I also made some minor documentations fixes in a case where a double tick (`) was included.

---

* changelog: New Lint: [`iter_filter_is_some`]
[#12004](rust-lang/rust#12004)
* changelog: New Lint: [`iter_filter_is_ok`]
[#12004](rust-lang/rust#12004)
@bors bors closed this as completed in 9dd2252 Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group
Projects
None yet
4 participants