Let chain temporaries should drop before else (original) (raw)

Due to #103034, now the implementation of let chains has changed, to drop temporaries created by let after the else block terminates. Prior behaviour has mirrored the pre-dropping bheaviour of if as well as bool conditionals in the let chain, while current behaviour mirrors if let. However, post-dropping is suboptimal (#103108). In particular, before #103034 this was compiling:

#![feature(let_chains)] struct Foo<'a>(&'a mut u32);

impl<'a> Drop for Foo<'a> { fn drop(&mut self) { *self.0 = 0; } }

fn main() { let mut foo = 0;

// compiles fine on rustc 1.66.0-nightly (a24a020e6 2022-10-18)
// but fails on rustc 1.66.0-nightly (4b8f43199 2022-10-19)
if true && let Foo(0) = Foo(&mut foo) {
} else {
    *&mut foo = 1;
}

// compiles fine
let Foo(0) = Foo(&mut foo) else {
    *&mut foo = 1;
    panic!()
};

// compile error - unfortunate but might not be fixed
if let Foo(0) = Foo(&mut foo) {
} else {
    *&mut foo = 1;
}

if true && matches!(Foo(&mut foo), Foo(0)) { // Compiles
} else {
    *&mut foo = 1;
}

}

But now it doesn't compile any more. I am not adding regression labels because it hasn't affected any of my own code, and it's a nightly feature.

For if let it might not be changed any more due to backwards compatibility concerns, but for let chains there are no such concerns as it is a new feature: code is only broken when developers edit it.

@rustbot label F-let_chains