Andrey Hanin
Andrey Hanin

Reputation: 113

Wrong lifetime inference for closure with implicit types

Here is trivial reproduction (nightly rustc as of 2-feb-23):

fn main() {
    let closure = |_v| {};
    // this one works fine
    // let closure = |_v: &_| {};
    {
        let x = 1;
        closure(&x);
    }
    {
        let y = 1;
        closure(&y);
    }
}

The error is:

6  |         let x = 1;
   |             - binding `x` declared here
7  |         closure(&x);
   |                 ^^ borrowed value does not live long enough
8  |     }
   |     - `x` dropped here while still borrowed
...
11 |         closure(&y);
   |         ------- borrow later used here

Which doesn't make sense, as variable x is not captured by the closure, but is just an argument passed by reference.

Providing an explicit reference for the closure parameter _v: &_ solves the issue, but shouldn't it be inferred automatically?

Is it some bug/limitation of the borrow checker? Or I'm missing something more fundamental here?

Upvotes: 5

Views: 76

Answers (1)

pigeonhands
pigeonhands

Reputation: 3414

This looks like it could be a bug with type inference to me.

I think what is happening is

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

    { 
        let x = 1; // Lifetime `a begins
        closure(&x); // closure is inferred to be fn(&'a i32)
        // Lifetime 'a end
    }
    {
        let y = 1; // Lifetime `b begins
        closure(&y); // attempt to call closure fn(&'a i32) with &'b i32
        // Lifetime 'b end
    }
}

but defining the closure as

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

Stops the compiling from inferring its lifetime and uses hrtb as it should.

Upvotes: 5

Related Questions