Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

map_flatten could suggest filter(matches!()) in case of map( match { _ => Option }).flatten() #12644

Open
matthiaskrgr opened this issue Apr 7, 2024 · 2 comments
Labels
C-enhancement Category: Enhancement of lints, like adding more cases or adding help messages L-suggestion Lint: Improving, adding or fixing lint suggestions

Comments

@matthiaskrgr
Copy link
Member

Description

I hope this not too convoluted 馃槄

I came across some code like

.iter()
        .map(|n| match n {
            0 | 2 | 5 => Some(n),
            _ => None,
        })
        .flatten()

clippy already recognizes the pattern and filter_map fires:

help: try replacing `map` with `filter_map` and remove the `.flatten()`
   |
6  ~         .filter_map(|n| match n {
7  +             0 | 2 | 5 => Some(n),
8  +             _ => None,
9  +         })

but, I believe it would be more elegant to completely forgo the "map" as well as the "match" by using filter(.. matches!()) in case we find ourselves matching on a pattern:

        .iter()
        .filter(|n| matches!(n, 0 | 2 | 5,))
        .collect::<Vec<&i32>>();

Version

rustc 1.79.0-nightly (aa1c45908 2024-04-06)
binary: rustc
commit-hash: aa1c45908df252a5b0c14e1bcb38c6c55ae02efe
commit-date: 2024-04-06
host: x86_64-unknown-linux-gnu
release: 1.79.0-nightly
LLVM version: 18.1.2

Additional Labels

No response

@matthiaskrgr matthiaskrgr added C-enhancement Category: Enhancement of lints, like adding more cases or adding help messages L-suggestion Lint: Improving, adding or fixing lint suggestions labels Apr 7, 2024
@matthiaskrgr
Copy link
Member Author

pub fn main() {
    let x = [1, 2, 4, 5, 3, 4, 5, 3, 2, 8, 6, 3];

    // finding
    let z = x
        .iter()
        .map(|n| match n {
            0 | 2 | 5 => Some(n),
            _ => None,
        })
        .flatten()
        .collect::<Vec<&i32>>();

    // suggest:
    let y = x
        .iter()
        .filter(|n| matches!(n, 0 | 2 | 5,))
        .collect::<Vec<&i32>>();

    dbg!(&z);
    dbg!(&y);
    assert_eq!(z,y);
}

@Alexendoo
Copy link
Member

The suggestion would trigger unnecessary_filter_map to go to a plain .filter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: Enhancement of lints, like adding more cases or adding help messages L-suggestion Lint: Improving, adding or fixing lint suggestions
Projects
None yet
Development

No branches or pull requests

2 participants