rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.14k stars 12.56k forks source link

Closure parameter lifetime inference erases hrtb #107589

Open pigeonhands opened 1 year ago

pigeonhands commented 1 year ago

It seems that closure type inference is causing "borrowed value does not live long enough" errors in places where it shouldent.

fn main() {
    let closure = |_v| {};
    {
        let x = 1;
        closure(&x);
    }
    {
        let y = 1;
        closure(&y);
    }
}
  --> src\main.rs:7:17
   |
7  |         closure(&x);
   |                 ^^ borrowed value does not live long enough
8  |     }
   |     - `x` dropped here while still borrowed
...
11 |         closure(&y);
   |         ------- borrow later used here

However changing the closure definition to

let closure = |_v: &_| {};

or moving the a definition and call into the same scope as the closure definition allows it to compile.

I assume what is happening is when closure is called with a, closure is inferred to be fn(&'1 i32), but then b is called so it is trying to call fn(&'1 i32) with a &'2 i32. But when it is defined as &_, the compiler does not infer the lifetime and instead uses hrbt.

Meta

rustc --version --verbose:

rustc 1.67.0 (fc594f156 2023-01-24)
binary: rustc
commit-hash: fc594f15669680fa70d255faec3ca3fb507c3405
commit-date: 2023-01-24
host: x86_64-pc-windows-msvc
release: 1.67.0
LLVM version: 15.0.6
MolotovCherry commented 1 year ago

Also happens in this thing I encountered yesterday. Same fix as above, use &_.

fn main() {
    let closure = |_v| {};

    let a = vec!["".to_string(), "".to_string(), "".to_string()];
    for b in a {
        closure(&b);
    }
}