This code fails to compile due to a borrow check error:
fn insert(v: &mut Option<u32>) -> Option<&u32> {
if let Some(r) = &v {
return Some(r)
}
*v = next_token();
v.as_ref()
}
fn next_token() -> Option<u32> {
unimplemented!()
}
Playground
The compiler complains that "cannot assign to *v because it is borrowed", which is a well-known borrow checker limitation. However, I was surprised to discover that it compiles using ref matching in if let:
fn insert(v: &mut Option<u32>) -> Option<&u32> {
if let Some(ref r) = v {
return Some(r)
}
*v = next_token();
v.as_ref()
}
Playground
I would expect the former code to desugar to the latter, as per "match ergonomics". In other words, I'd expect both examples to be accepted by the compiler, or both to be rejected (ideally the former).
This issue is not intended as a report regarding the borrow checker limitation that will be fixed by Polonius. It is about the perceived equivalence of match-ergonomics match and the manually written one, which I'd expect to lead to the same borrow-checking outcomes.
Meta
This is on rustc 1.79.
This code fails to compile due to a borrow check error:
Playground
The compiler complains that "cannot assign to
*vbecause it is borrowed", which is a well-known borrow checker limitation. However, I was surprised to discover that it compiles usingrefmatching inif let:Playground
I would expect the former code to desugar to the latter, as per "match ergonomics". In other words, I'd expect both examples to be accepted by the compiler, or both to be rejected (ideally the former).
This issue is not intended as a report regarding the borrow checker limitation that will be fixed by Polonius. It is about the perceived equivalence of match-ergonomics match and the manually written one, which I'd expect to lead to the same borrow-checking outcomes.
Meta
This is on rustc 1.79.