Default match bindings - The Edition Guide

# Default match bindings

Have you ever had a borrowed `Option<T>` and tried to match on it? You probably wrote this:

    let s: &Option<String> = &Some("hello".to_string());

    match s {
        Some(s) => println!("s is: {}", s),
        _ => (),
    };

In Rust 2015, this would fail to compile, and you would have to write the following instead:

    // Rust 2015

    let s: &Option<String> = &Some("hello".to_string());

    match s {
        &Some(ref s) => println!("s is: {}", s),
        _ => (),
    };

Rust 2018, by contrast, will infer the `&`s and `ref`s, and your original code will Just Work.

This affects not just `match`, but patterns everywhere, such as in `let` statements, closure arguments, and `for` loops.

## More details

The mental model of patterns has shifted a bit with this change, to bring it into line with other aspects of the language. For example, when writing a `for` loop, you can iterate over borrowed contents of a collection by borrowing the collection itself:

    let my_vec: Vec<i32> = vec![0, 1, 2];

    for x in &my_vec { ... }

The idea is that an `&T` can be understood as a borrowed view of `T`, and so when you iterate, match, or otherwise destructure a `&T` you get a borrowed view of its internals as well.

More formally, patterns have a "binding mode," which is either by value (`x`), by reference (`ref x`), or by mutable reference (`ref mut x`). In Rust 2015, `match` always started in by-value mode, and required you to explicitly write `ref` or `ref mut` in patterns to switch to a borrowing mode. In Rust 2018, the type of the value being matched informs the binding mode, so that if you match against an `&Option<String>` with a `Some` variant, you are put into `ref` mode automatically, giving you a borrowed view of the internal data. Similarly, `&mut Option<String>` would give you a `ref mut` view.