Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: both compiles successfully Instead, this happened: fails to compile <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
This may have something to do with , as there is something about let_chain drops here as well, but I don't for sure.
The same behaviour happens with an older compiler version. Here goes an example that compiles with . It is not up to me to decide if this behaviour is a blocker that will revert stabilization but in case of such event, I won't have enough free time to investigate and fix stuff in the near future.
Personally and despite the differences, I think that the version is "correct" and the nested version is surprisingly holding a reference of an owned structure () without an explicit bind.
drops the scrutinee after the statement.
cc who have been dealing with dropping stuff related to
Some things that might be helpful to know: The drop order changes for in also had borrow checker impact and made an example compile (see the PR's thread). I'm not a borrow checker expert, so I might be wrong, but this too might be fixed by drop order changes alone. In I'm studying drop order impacts of conditional statements, motivated by let else, but the test that PR adds also includes let chains. There I observed that let chains generally behave drop order wise like when there is a involved, and when it's a bool. I have only studied them regarding the body contained inside though. This table provides a summary of drop orders (disclaimer: it's outdated for let else):
I've locally amended of to add if let chains: And this is the output: Which actually runs counter to what I wrote above, because it predrops. It seems that it depends on whether the in the chain is preceded by a or not: if you change the line with to , removing the , you get this: So that rule that I wrote above is not correct, but the underlying behaviour is more complicated. Hmmm...
Thanks
claim
pointed this out to me. It may be motivation to revert the stablization of let-chains on beta. Lets try to ensure we talk about this at Thursday triage label I-compiler-nominated
False alarm; pointed out to me that let-chains is already been marked unstable (on beta and nightly). label: -I-compiler-nominated

Discussion:
) => { // For shortcircuiting operators, mark the RHS as a terminating // scope since it only executes conditionally. <del> terminating(r.hir_id.local_id); } </del> <ins> // `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries // should live beyond the immediate expression if !matches!(r.kind, hir::ExprKind::Let(_)) { terminating(r.hir_id.local_id); } } </ins> hir::ExprKind::If(_, ref then, Some(ref otherwise)) => { terminating(then.hir_id.local_id); terminating(otherwise.hir_id.local_id);

// take the "else" branch if self.option_loud_drop(6).is_some() // 2 && self.option_loud_drop(5).is_some() // 1 <del> && let None = self.option_loud_drop(7) { // 3 </del> <ins> && let None = self.option_loud_drop(8) { // 4 </ins> unreachable!(); } else { <del> self.print(8); // 4 </del> <ins> self.print(7); // 3 </ins> } // let exprs interspersed

<ins> // check-pass // compile-flags: -Z validate-mir #![feature(let_chains)] fn let_chains(entry: std::io::Result<std::fs::DirEntry>) { if let Ok(entry) = entry && let Some(s) = entry.file_name().to_str() && s.contains("") {} } fn main() {} </ins>

pub struct DropLogger<'a, T> { extra: T, id: usize, <del> log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>> </del> <ins> log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>, </ins> } impl<'a, T> Drop for DropLogger<'a, T> {

else { // 10 is not constructed d(10, None) <del> } </del> <ins> }, </ins> ); <del> assert_eq!(get(), vec![3, 8, 7, 1, 2]); </del> <ins> assert_eq!(get(), vec![8, 7, 1, 3, 2]); </ins> } assert_eq!(get(), vec![0, 4, 6, 9, 5]);

panic::panic_any(InjectedFailure) ); }); <del> assert_eq!(get(), vec![14, 19, 20, 17, 15, 11, 18, 16, 12, 13]); </del> <ins> assert_eq!(get(), vec![20, 17, 15, 11, 19, 18, 16, 12, 14, 13]); </ins> }