New lint: `unnecessary_map_or`
Closes https://github.com/rust-lang/rust-clippy/issues/10118
This lint checks map_or method calls to check if they can be consolidated down to something simpler and/or more readable.
For example, the code
let x = Some(5);
x.map_or(false, |n| n == 5)
can be rewritten as
let x = Some(5);
x == Some(5)
In addition, when the closure is more complex, the code can be altered from, say,
let x = Ok::<Vec<i32>, i32>(vec![5]);
x.map_or(false, |n| n == [5])
into
let x = Ok::<Vec<i32>, i32>(vec![5]);
x.is_some_and(|n| n == [5])
This lint also considers cases where the map_or can be chained with other method calls, and accommodates accordingly by adding extra parentheses as needed to the suggestion.
changelog: add new lint unnecessary_map_or
r? @Centri3
(rustbot has picked a reviewer for you, use r? to override)
@Jacherr this seems to be waiting on you, since Catherine left you a review. @rustbot author
Hi, apologies for the lack of movement on this. I’ll make changes based on the review now, and once everything is up to standard I’ll go through the conflicts.
@rustbot ready
:umbrella: The latest upstream changes (presumably #12310) made this pull request unmergeable. Please resolve the merge conflicts.
:umbrella: The latest upstream changes (presumably #12507) made this pull request unmergeable. Please resolve the merge conflicts.
Hey @Jacherr Sorry for the delay. @Centri3 was sadly busy, but now she indicated that she'll have time for reviews again. Would you mind rebasing again? Next time there is a long delay, you can also pick a new reviewer with r? clippy.
I did rebase but it's not showing up in the PR for some reason 😕
:umbrella: The latest upstream changes (presumably #12999) made this pull request unmergeable. Please resolve the merge conflicts.
Never mind: My GH view was outdated
Hey, this is a ping from triage. @Centri3 can you give this PR a review? It's totally fine if you don't have the time right now, you can reassign the PR to a random team member using r? clippy.
@rustbot ready
:umbrella: The latest upstream changes (presumably #13168) made this pull request unmergeable. Please resolve the merge conflicts.
:umbrella: The latest upstream changes (presumably #13496) made this pull request unmergeable. Please resolve the merge conflicts.
Apologies for the slow turnover again. I hope this is the last of the issues now and this can finally be merged 😅
It looks like you marked the comment in https://github.com/rust-lang/rust-clippy/pull/11796#discussion_r1789240785 as resolved but it is not. The example:
fn main() {
struct S;
let r: Result<i32, S> = Ok(3);
let _ = r.map_or(false, |x| x == 7);
}
will incorrectly suggest using (r == Ok(7)) (also, note the extra parentheses, but this is not the main problem, which is that Result<i32, S> does not implement PartialEq). A proposed fix is given in the linked comment.
Could you also add this as a testcase? As well as one where S is a type which implements PartialEq (such as i32), to check for the extra parentheses?
Is it time to open a FCP for this lint? I keep seeing .map_or(false, …) used everywhere.
:umbrella: The latest upstream changes (presumably #13437) made this pull request unmergeable. Please resolve the merge conflicts.
Opened the FCP. Can you squash?
Squash done, ready for final comments/changes then hopefully can finally get this merged. Apologies again for how long this took.
@Jacherr It looks like .map_or(true, …) can be linted as well, using .is_none_or(…). I played with it a bit but I have to go AFK right now, so feel free to integrate the top commit from https://github.com/samueltardieu/rust-clippy/commits/push-oqltkmvvzmlq/ in your code if you wish, and update all the lints which trigger this code. Otherwise, I'll submit a complete PR after yours is merged.
Note that tests that don't involve PartialEq are machine applicable as far as I can see, so I've changed this as well, but not looked closely at why the others aren't.
I am happy with merging this as-is if no concerns come up, and having that done later.
I am happy with merging this as-is if no concerns come up, and having that done later.
This seems reasonable indeed.
:umbrella: The latest upstream changes (presumably #13639) made this pull request unmergeable. Please resolve the merge conflicts.
@Jacherr Commit https://github.com/rust-lang/rust-clippy/pull/13653/commits/430235e80d022faefb866b1e8e193e1d49f1501f is an updated version of your commit compatible with the current master
(an alternative is to merge https://github.com/rust-lang/rust-clippy/pull/13653 which contains this PR, updated, and the .map_or(true, …) case as well)
Hopefully, everything is in order for merge now. Ideally, as mentioned in the FCP, this can be merged and the additional map_or(true case added in post. It would be nice, at least for me, to put this PR to bed properly given how long it's been going back and forth.
Thanks for your work on this :) I doubt anybody will object the lint being added so let's put it to rest :heart: