rustsyntax

What does the Some(..) syntax mean?


I wrote this snippet:

let my_option: Option<()> = None;
if my_option.is_some() {
    my_option.unwrap();
}

Clippy is telling me to use:

if let Some(..) = my_option {
    my_option.unwrap();
}

What does Some(..) mean? Is it just dropping the value similar to how using _ would in some cases? And where can I find more information about when and where I can use the ..?


Solution

  • I think the Clippy warning is slightly misleading. Let's first look at the full warning message:

    warning: called `unwrap` on `my_option` after checking its variant with `is_some`
     --> src/main.rs:4:9
      |
    3 |     if my_option.is_some() {
      |     ---------------------- help: try: `if let Some(..) = my_option`
    4 |         my_option.unwrap();
      |         ^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(clippy::unnecessary_unwrap)]` on by default
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
    

    Clippy is complaining about the use of unwrap() after checking with is_some(). If you use is_some() only or unwrap() only, Clippy won't complain. It's only unwrapping after checking that's considered unidiomatic, since it can be easier done using if let.

    I believe the reason for Clippy to suggest if let Some(..) = my_option is that the code does not track how the inner value is used later, so the suggestion needs to be somehow generic. In practice, you would hardly ever literally write .. here, but instead write something like

    if let Some(value) = my_option
    

    to bind the inner value to a variable. Also note that if let Some(..) = my_option does not consume the option, while if let Some(value) = my_option does (if the inner type is not Copy).

    In summary: