Skip to content

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

Open
@qsantos

Description

@qsantos

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: Enhancement of lints, like adding more cases or adding help messages

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions