Static rustc_lint_defs::builtin::DISJOINT_CAPTURE_MIGRATION[−][src]

pub static DISJOINT_CAPTURE_MIGRATION: &Lint
Expand description

The disjoint_capture_migration lint detects variables that aren’t completely captured in Rust 2021 and affect the Drop order of at least one path starting at this variable. It can also detect when a variable implements a trait, but one of its field 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

ⓘ
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(disjoint_capture_migration)]
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 thread safely.