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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify if-let-Some-else-None using question mark operator #13626

Open
qsantos opened this issue Oct 29, 2024 · 0 comments
Open

Simplify if-let-Some-else-None using question mark operator #13626

qsantos opened this issue Oct 29, 2024 · 0 comments
Labels
C-enhancement Category: Enhancement of lints, like adding more cases or adding help messages

Comments

@qsantos
Copy link

qsantos commented Oct 29, 2024

Consider the code below.

pub fn f(x: Option<u32>) -> Option<u32> {
    if let Some(x) = x {
        dbg!(x);
        Some(x * 2)
    } else {
        None
    }
}

Standard Clippy produces no warning. More exhaustive options suggest code that is no significantly better:

$ cargo clippy --all -- -W clippy::all -W clippy::nursery
error: use Option::map_or instead of an if let/else
 --> src/lib.rs:2:5
  |
2 | /     if let Some(x) = x {
3 | |         dbg!(x);
4 | |         Some(x * 2)
5 | |     } else {
6 | |         None
7 | |     }
  | |_____^
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else
  = note: `-D clippy::option-if-let-else` implied by `-D warnings`
  = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]`
help: try
  |
2 ~     x.map_or(None, |x| {
3 +         dbg!(x);
4 +         Some(x * 2)
5 +     })
  |

However, the code can be written with less nesting, using the question mark operator:

pub fn f(x: Option<u32>) -> Option<u32> {
    let x = x?;
    dbg!(x);
    Some(x * 2)
}

Note that Clippy does suggest that for the code below:

pub fn f(x: Option<u32>) -> Option<u32> {
    let Some(x) = x else {
        return None;
    };
    dbg!(x);
    Some(x * 2)
}
error: this `let...else` may be rewritten with the `?` operator
 --> src/lib.rs:2:5
  |
2 | /     let Some(x) = x else {
3 | |         return None;
4 | |     };
  | |______^ help: replace it with: `let x = x?;`
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#question_mark
  = note: `-D clippy::question-mark` implied by `-D warnings`
  = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`

This pattern is particularly frequent when implementing iterators.

@samueltardieu samueltardieu added the C-enhancement Category: Enhancement of lints, like adding more cases or adding help messages label Oct 30, 2024
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
Projects
None yet
Development

No branches or pull requests

2 participants