## RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES

# Static RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES

Source

    pub static RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES: &'static Lint

Expand description

The `rust_2021_incompatible_closure_captures` lint detects variables that aren’t completely captured in Rust 2021, such that the `Drop` order of their fields may differ between Rust 2018 and 2021.

It can also detect when a variable implements a trait like `Send`, but one of its fields does not, and the field is captured by a closure and used with the assumption that said field implements the same trait as the root variable.

#### §Example of drop reorder

ⓘ

    #![deny(rust_2021_incompatible_closure_captures)]

    struct FancyInteger(i32);

    impl Drop for FancyInteger {
        fn drop(&mut self) {
            println!("Just dropped {}", self.0);
        }
    }

    struct Point { x: FancyInteger, y: FancyInteger }

    fn main() {
      let p = Point { x: FancyInteger(10), y: FancyInteger(20) };

      let c = || {
         let x = p.x;
      };

      c();

      // ... More code ...
    }

{{produces}}

#### §Explanation

In the above example, `p.y` will be dropped at the end of `f` instead of with `c` in Rust 2021.

#### §Example of auto-trait

ⓘ

    #![deny(rust_2021_incompatible_closure_captures)]
    use std::thread;

    struct Pointer(*mut i32);
    unsafe impl Send for Pointer {}

    fn main() {
        let mut f = 10;
        let fptr = Pointer(&mut f as *mut i32);
        thread::spawn(move || unsafe {
            *fptr.0 = 20;
        });
    }

{{produces}}

#### §Explanation

In the above example, only `fptr.0` is captured in Rust 2021. The field is of type `*mut i32`, which doesn’t implement `Send`, making the code invalid as the field cannot be sent between threads safely.