//@ run-rustfix #![deny(if_let_rescope)] #![feature(stmt_expr_attributes)] #![allow(irrefutable_let_patterns, unused_parens)] fn droppy() -> Droppy { Droppy } struct Droppy; impl Drop for Droppy { fn drop(&mut self) { println!("dropped"); } } impl Droppy { const fn get(&self) -> Option { None } } fn main() { if let Some(_value) = droppy().get() { // Should not lint } match droppy().get() { Some(_value) => { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 // do something } _ => { //~^ HELP: the value is now dropped here in Edition 2024 // do something else }} match droppy().get() { Some(_value) => { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 // do something } _ => { match droppy().get() { Some(_value) => { //~^ HELP: the value is now dropped here in Edition 2024 // do something else } _ => {}}}} //~^ HELP: the value is now dropped here in Edition 2024 if droppy().get().is_some() { // Should not lint } else { match droppy().get() { Some(_value) => { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } _ => if droppy().get().is_none() { //~^ HELP: the value is now dropped here in Edition 2024 }}} if let Some(1) = { match Droppy.get() { Some(_value) => { Some(1) } _ => { None }} } { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } if let () = { if let Some(_value) = Droppy.get() {} } { // This should not lint. // This `if let` sits is a tail expression of a block. // In Edition 2024, the temporaries are dropped before exiting the surrounding block. } #[rustfmt::skip] if (match droppy().get() { Some(_value) => { true } _ => { false }}) { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 // do something } else if (((match droppy().get() { Some(_value) => { true } _ => { false }}))) { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } while let Some(_value) = droppy().get() { // Should not lint break; } while (match droppy().get() { Some(_value) => { false } _ => { true }}) { //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } match Some((droppy(), ()).1) { Some(_value) => {} _ => {}} //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 //~| WARN: this changes meaning in Rust 2024 //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 // We want to keep the `if let`s below as direct descendents of match arms, // so the formatting is suppressed. #[rustfmt::skip] match droppy().get() { _ => if let Some(_value) = droppy().get() {}, // Should not lint // There is implicitly a block surrounding the `if let`. // Given that it is a tail expression, the temporaries are dropped duly before // the execution is exiting the `match`. } if let Some(_value) = droppy().get() {} }