Pre-Pre-RFC: `let else match` statement

If we had a feature where the compiler could be aware of which patterns are unreachable/impossible for the value in some variable/place based on control-flow and lack of intermediate mutable access[1], then something like

let Ok(Some(foo)) = get_foo() else match {
    Ok(None) => return Err("missing foo"),
    Err(err) => return Err("failed to get foo"),
};

could be written as

let foo_res = get_foo();
let Ok(Some(foo)) = foo_res else {
    match foo_res {
        Ok(None) => return Err("missing foo"),
        Err(err) => return Err("failed to get foo"),
    }
};

which is at least somewhat nicer than the already possible alternative of

let foo_res = get_foo();
let Ok(Some(foo)) = foo_res else {
    match foo_res {
        Ok(None) => return Err("missing foo"),
        Err(err) => return Err("failed to get foo"),
        Ok(Some(_)) => unreachable!(),
    }
};

I could also imagine that such a feature could be followed with allowing field-access in enums in cases where the variant is known. E.g. instead of

let Ok(foo) = f() else match {
    Err(e) => {
        cleanup();
        panic!("got an error in situation X: {}", e);
    }
};

one could perhaps just do

let f_res = f();
let Ok(foo) = f_res else {
    cleanup();
    panic!("got an error in situation X: {}", f_res.0);
};

Disadvantage: You need the extra let some_name = …EXPR… if it’s a value that needs to be computed first. Advantage: you don’t need the single-arm match cases that would probably be common with a else match feature.


  1. I am aware that this sounds like a hard to pull off feature, and discussing the technicalities would quickly become off-topic here, yet I also believe that some MVP with practical use should be doable, and further refinement could be added later ↩︎

6 Likes