Description
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