I’m not sure if this has been brought up before but using ‘ref’ in pattern matching can be quite counter-intuitive. I believe a more apt way of expressing reference binding should consist of something that has the opposite meaning to ‘ref’. Let me demonstrate:
let a = x; // Match a to x. No problem - understood.
let b = &x; // Match b to reference of x. No problem - understood.
let ref c = x; // Match reference of c to x? Hmm, if we destructure this, x is a reference to some value. Thus c should refer to that value right? WRONG.
let &c = x; // This is actually the correct way to express the previous line.
It is too easy for a casual reader who is not very acquainted with rust to confuse ref and &. Even after having given the explanation of what ref does, it can still leave quite some dissonance. I would consider this a papercut. Now consider a ‘deref’ keyword instead:
let deref c = x; // Match the dereference of c to x. If we destructure this, x is a dereference of some reference. Thus c refers to that reference!
Doesn’t the above feel better to you? But there is a problem with using ‘deref’ like that. Rust has already established a convention that prefixing keywords do not take part in pattern matching, but are rather a property of the bound name. For example:
let mut a = b; // mut is a property of the bound name a, not that b is a mut value for some value which a binds to.
let ref c = x; // ref technically follows this convention, but as I mentioned, reading this can be a papercut to understanding Rust
My proposal would be to use the following:
let *c = x; // * is already the dereference operator
let *mut c = x; // Mutable reference