I'd have imagined a pattern match where there is a bind-by-move on one hand, and a bind-by-ref on the other, such as in:
fn main ()
{
let mut it = (Some(vec![42]), Some(vec![]));
if let (Some(v), Some(ref mut vs)) = it {
vs.push(v);
}
dbg!(&it.1);
}
but sadly this currently fails with:
error[E0009]: cannot bind by-move and by-ref in the same pattern
And yet, there is a:
This limitation may be removed in a future version of Rust
in the detailed error message.
(And yes, replacing = it
by = (it.0, it.1.as_mut())
works, and does not require ref
s, but that is implicitely performing one more nested pattern match on the .1
field, so I think it would qualify as less expressive).
A similar code that works right now is when the by-move
is Copy
(since it can still be by-ref
under the hood, I imagine):
let mut it = (Some(42), Some(vec![]));
if let (Some(v), Some(ref mut vs)) = it {
vs.push(v);
}
dbg!(&it.1);
which, imho, is a bit more expressive than:
let mut it = (Some(42), Some(vec![]));
if let (Some(v), Some(vs)) = (it.0, &mut it.1) {
vs.push(v);
}
dbg!(&it.1);
which has required explicitly splitting the matched expression.
-
to my surprise, the following does not work despite match
ergonomics:
if let (Some(&mut v), Some(v)) = &mut it {
- and even if it did, that would still be 2 x
&mut
vs. 1 x ref mut
.