0

I do not understand why the & in &x in the following Rust syntax actually copies the value behind a reference, hence, makes an owned value. In some sort, the & performs an "upgrade" of the value here, surprisingly. I expected that & would only create a reference (similar to the ref keyword) but never a copied version from a reference. To better demonstrate it, I provide a small example where rustc tells the actual type with an error message:

let opt: Option<u8> = Option::from(42_u8);
opt.filter(|x| {
    // compiler fails: says 'x' has type "&u8"
    let _: () = x;
    true
});
opt.filter(|&x| {
    // compiler fails: says 'x' has type "u8"
    let _: () = x;
    true
});

What is going on here? Any reference to the language documentation? This looks weird to me and I never saw this in my past four years with Rust.. or am I missing something?

phip1611
  • 5,460
  • 4
  • 30
  • 57

2 Answers2

2

In expressions, & indeed takes a reference.

But in patterns, & dereferences a reference.

This is easy to remember if you see the symmetry:

let &x = &y; // Take reference on the expression, dereference on the pattern. At the end x == y.

Here's the reference docs on reference patterns.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
0

This is explained in the reference in Patterns/Reference patterns.

A minimal example to see this kind of an "upgrade" is the following:

fn main() {
    match &5 {
        &x => {
            // compiles
            let _: i32 = x;
        }
    }
}
phip1611
  • 5,460
  • 4
  • 30
  • 57