-
Notifications
You must be signed in to change notification settings - Fork 14k
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.