21.15 The let else Construct (Rust 1.65+)

Rust 1.65 introduced the let else statement, which allows a refutable pattern in a let binding. Concretely:

  • If the pattern match from the assigned expression succeeds, its bindings are introduced into the surrounding scope, just like a regular let would.
  • If the pattern match fails, the else block must produce divergent control flow (for example, by using return, break, or panic!). In other words, the else block cannot simply continue execution—it must exit the current function, loop, or scope.
fn process_value(opt: Option<i32>) {
    // Here, "Some(val)" is a refutable pattern
    let Some(val) = opt else {
        println!("No value provided!");
        return;
    };
    // If we reached this line, we know "opt" matched "Some(val)",
    // and "val" is introduced into this scope.
    println!("Got value: {}", val);
}

fn main() {
    process_value(None);
    process_value(Some(42));
}

In this example, Some(val) is a refutable pattern—None would fail to match. If opt is None, control flow diverges in the else block via return. Otherwise, val is introduced into the surrounding scope, and execution continues normally.