Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match ergonomics and & pattern

Consider following code

fn main() {
    let s = (&&0,);
    let (x,) = s; // &&i32
    let (&y,) = s; // &i32
    let (&&z,) = s; // i32

    let t = &(&0,);
    let (x,) = t; // &&i32
    let (&y,) = t; // i32

    let u = &&(0,);
    let (x,) = u; // &i32
    let (&y,) = u; // mismatched types expected type `{integer}` found reference `&_`
}

Could someone explain, why & pattern behaves differently in every case? I suppose it is tied somehow to match ergonomics, maybe some coercions come into play? But I can't wrap my head around it.

like image 647
ZeroXbot Avatar asked Feb 13 '26 21:02

ZeroXbot


1 Answers

You are correct, this is due to match ergonomics. The first case should hopefully be self explanatory, but the second and third cases can be a bit counter-intuitive.

In the second case:

  • (x,) is a non-reference pattern (see the second example in the RFC). The t tuple reference is dereferenced, and x is bound as a ref as it also is a non-reference pattern. Note that t.0 was a reference to begin with, thus resulting in x being a double reference.

  • (&y,) is also a non-reference pattern. The t tuple is dereferenced again to a (&i32,). However, &y is a reference pattern being matched to a &i32 reference. Hence y is bound with move mode and is an i32.

In the third case:

  • Using the same reasoning as the second case, u is dereferenced via Deref coercion to an (i32,), and x, a non-reference pattern, is bound in ref mode. Hence x is an &i32.

  • Again with the same reasoning as the second case, u is dereferenced to an (i32,). The &y reference pattern is then matched to an i32, a non-reference, which causes an error.

like image 125
EvilTak Avatar answered Feb 15 '26 10:02

EvilTak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!