rustc_lint::if_let_rescope

Static IF_LET_RESCOPE

source
pub static IF_LET_RESCOPE: &Lint
Expand description

The if_let_rescope lint detects cases where a temporary value with significant drop is generated on the right hand side of if let and suggests a rewrite into match when possible.

§Example

#![cfg_attr(not(bootstrap), feature(if_let_rescope))] // Simplify this in bootstrap bump.
#![warn(if_let_rescope)]
#![allow(unused_variables)]

struct Droppy;
impl Drop for Droppy {
    fn drop(&mut self) {
        // Custom destructor, including this `drop` implementation, is considered
        // significant.
        // Rust does not check whether this destructor emits side-effects that can
        // lead to observable change in program semantics, when the drop order changes.
        // Rust biases to be on the safe side, so that you can apply discretion whether
        // this change indeed breaches any contract or specification that your code needs
        // to honour.
        println!("dropped");
    }
}
impl Droppy {
    fn get(&self) -> Option<u8> {
        None
    }
}

fn main() {
    if let Some(value) = Droppy.get() {
        // do something
    } else {
        // do something else
    }
}

{{produces}}

§Explanation

With Edition 2024, temporaries generated while evaluating if lets will be dropped before the else block. This lint captures a possible change in runtime behaviour due to a change in sequence of calls to significant Drop::drop destructors.

A significant Drop::drop destructor here refers to an explicit, arbitrary implementation of the Drop trait on the type with exceptions including Vec, Box, Rc, BTreeMap and HashMap that are marked by the compiler otherwise so long that the generic types have no significant destructor recursively. In other words, a type has a significant drop destructor when it has a Drop implementation or its destructor invokes a significant destructor on a type. Since we cannot completely reason about the change by just inspecting the existence of a significant destructor, this lint remains only a suggestion and is set to allow by default.

Whenever possible, a rewrite into an equivalent match expression that observe the same order of calls to such destructors is proposed by this lint. Authors may take their own discretion whether the rewrite suggestion shall be accepted, or rejected to continue the use of the if let expression.