ideasman42
ideasman42

Reputation: 48178

Can the `let Some(var) = option;` syntax be used in a situation where it's known that it's not `None`?

When an option variable is known to be non-None, its normally fine to write:

let var = option_var.unwrap();

In one case I ran into, this caused an error about moving out of borrowed context.

if let Some(var) = option_var { ... }

(Handy since it allows Some(ref mut var) = option_var too).

This works, however in this case I don't want this to be an if statement. Writing let Some(var) = option_var; fails with the error "pattern None not covered".

To be clear this question isn't about borrowed context.

Can the let Some(var) = option; syntax be used in a situation where it's known that it's not None? Resolving the "Pattern None not covered" warning? Or is this simply not supported outside an if statement?

Upvotes: 1

Views: 4078

Answers (2)

Tanin
Tanin

Reputation: 1933

I've just encountered a similar problem with enum like:

let SomeEnum::First(first) = item;

I know item is SomeEnum::First. But Rust won't let me compile.

One way to bypass this problem is to use a macro like this:

    macro_rules! unwrap {
        ($enum:path, $expr:expr) => {{
            if let $enum(item) = $expr {
                item
            } else {
                panic!()
            }
        }};
    }

And you can invoke unwrap! like this:

let first = unwrap!(SomeEnum::First, item);

PS. I'm using this in my tests. It helps shorten the tests.

Upvotes: 6

ljedrz
ljedrz

Reputation: 22273

Given the following case:

fn main() {
    let foo = Some(1);
    let Some(bar) = foo;
}

error[E0005]: refutable pattern in local binding: None not covered

let Some(x) = y introduces a pattern; let and match statements and function arguments are pattern-matching contexts, but since in this case the pattern doesn't cover the other possible case, it is not a valid pattern matching context.

The only contexts which the let Some(x) = y statement is applicable to are the if let expressions and while let loops.

If you are sure (e.g. with an earlier assert!() or if it is introduced "by hand") that a None is not possible, you can just use unwrap().

Upvotes: 8

Related Questions