pub static RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES: &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.