use either::Either;
struct A;
struct B;
struct AW<'a>(&'a mut A);
impl<'a> Drop for AW<'a> {
fn drop(&mut self) {
println!("AW drop");
}
}
fn cap(_: &mut A) -> Either::<AW<'_>, B> {
unimplemented!()
}
pub fn main() {
let mut a = A;
let b = cap(&mut a);
match b {
Either::Left(a) => {
drop(a);
// b is destructed, and drop(a) already called
},
Either::Right(y) => {
a = A;
// b is destructed
}
}; // No way is the compiler going to drop b at this point in either case
}
In this piece of code, the compiler borrows b for the entire duration of match. The explanation it gives is that it needs to run drop on b at the end of the match.
However, that's not the case at all. b is partially moved in both arms, its destructor cannot be called at the end of match.
Yet the compiler still insists on borrowing b for the whole match, preventing me from modifying a in the Right arm, even if it's safe.
playground link: Rust Playground