The ref keyword is like the opposite of & in patterns; this says “please bind ref to be a &String , don’t try to move it out. In other words, the & in &Some is matching against a reference, but refcreates a reference. ref mut is like ref , but for mutable references.
Anyway, today’s Rust doesn’t work like this. If you try to match on something borrowed, then all of the bindings you create will attempt to borrow as well. This means that the original code works as you’d expect.
Because Rust is backwards compatible, we couldn’t remove ref and ref mut , and they’re sometimes useful in obscure situations, where you want to partially borrow part of a struct as mutable and another part as immutable. But you may see them in older Rust code, so knowing what they do is still useful.
However, I just struggled for quite a while trying to figure out why updating an array in a destructure wasn't affecting the original array... after all, I received the struct as a reference - why wouldn't it work?
I believe, that if you specify mut a, mut b then the compiler will think that you're trying to specify the modifiers (ref and mut) and therefore not infer them, and in the second bit of code where you mention the necessity of &mut, if I read it correctly, the docs you quoted meant that specifying you're destructuring a reference to a variable makes all the variables you're destructuring references as well. It's abit murky in this case because [f32; 4] is Clone and therefore will be cloned when necessary.
Sorry for replying to an old thread, but I am unable to find that section in the Rust Book. Can you post a link? I keep reading that ref keyword is "legacy" but want to solidify my understanding so I can know when it's actually needed.
Aside: this sentence from the quoted part of the docs makes me sad:
This means that the original code works as you’d expect.
I've said this before but because the wording here ("legacy") suggests a recommendation against explicit refs, I feel this is warranted.
I specifically wouldn't expect a non-pointer type (in the pattern) to get accepted in the place of a pointer type (in the expression being pattern matched against), even less so to automagically propagate references to inner subpatterns, because 1. references themselves are patterns, and 2. the distinction between reference and non-reference types is very clear and important in most other parts of the language.
Therefore I still use ref, and consider it a massive readability win over default binding modes, even in new code I write.