Surprising destructuring behavior

Given that i32 implements Copy, I was expecting x2 to be an i32 like x1 instead of &i32. What is the special rule which governs this case?

struct Foo {
    value: i32,
}

fn get_var_type<T>(_var: &T) -> &'static str {
    std::any::type_name::<T>()
}

fn main() {
    let f = Foo { value: 1 };
    let rf = &f;

    let x1 = rf.value;
    println!("x1 has type {}", get_var_type(&x1));

    let Foo { value: x2 } = rf;
    println!("x2 has type {}", get_var_type(&x2));
}

(Playground)

Output:

x1 has type i32
x2 has type &i32

this is called "binding modes", it's part of the pattern mathcing ergonomics feature:

to make x2 bound by value, you write & in the pattern to explicitly disable the default "auto" binding mode:

let &Foo { value: x2 } = rf;
println!("x2 has type {}", get_var_type(&x2));
3 Likes

Oh, cool! Thanks!

And in contrast, rf.value is a field access expression which can be considered to desugar to something like (*rf).value.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.