Description
The following example does not get a migration warning in Rust 2018 (or Rust 2021) -- (playground):
#![warn(rust_2021_incompatible_closure_captures)]
fn main() {
struct Foo(u32);
impl Drop for Foo {
fn drop(&mut self) {
println!("dropped {}", self.0);
}
}
let f0 = Foo(0);
let f1 = Foo(1);
let c0 = move || {
let _ = f0;
};
let c1 = move || {
let _ = &f1;
};
println!("dropping 0");
drop(c0);
println!("dropping 1");
drop(c1);
println!("dropped all");
}
The behavior of let _ = x
changed in the new edition, but there ought to have been a warning.
Original issue
See the below code
fn main() {
struct Foo(u32);
impl Drop for Foo {
fn drop(&mut self) {
println!("dropped {}", self.0);
}
}
let f0 = Foo(0);
let f1 = Foo(1);
let c0 = move || {
let _ = f0;
};
let c1 = move || {
let _ = &f1;
};
println!("dropping 0");
drop(c0);
println!("dropping 1");
drop(c1);
println!("dropped all");
}
With 2018 edition (playground link) this prints
dropping 0
dropped 0
dropping 1
dropped 1
dropped all
With 2021 edition (playground link) this prints
dropping 0
dropping 1
dropped 1
dropped all
dropped 0
That is, with the 2021 edition the first closure is apparently not capturing f0
at all (and drops it at the end of main
) while with the 2018 edition it did.
This might be intentional and expected or not, which is why I'm creating this issue. It might be worth mentioning it as a potential porting trap in the edition guide. Note that cargo fix --edition
did not catch this one (but a couple of others where the behaviour difference was irrelevant).
This subtle behaviour change caused a test in gtk-rs to timeout and fail.