It may be by design but I'm still genuinely surprised by this behavior.
enum E {
A(i32),
B,
}
// Good
fn test(e: &mut E) -> &i32 {
match e {
E::A(v) => v,
E::B => {
*e = E::A(0);
let E::A(v) = e else { panic!() };
v
}
}
}
struct F {
e: E,
}
// Breaks
fn test2(f: &mut F) -> &i32 {
match &f.e {
E::A(v) => v,
E::B => {
f.e = E::A(0);
//cannot assign to `f.e` because it is borrowed
//`f.e` is assigned to here but it was already borrowed
let E::A(v) = &f.e else { panic!() };
v
}
}
}
// Good
fn test3(f: &mut F) -> &i32 {
let e = &mut f.e;
match e {
E::A(v) => v,
E::B => {
*e = E::A(0);
let E::A(v) = e else { panic!() };
v
}
}
}
In test2
's first match arm, I thought rustc would recognize v
to be a splitting borrow of f.e
. But instead, rustc seems to reason v
as borrowing the entirety of f
and thus spit out lifetime error.