使用隐式类型闭包的错误生存期推断

Wrong lifetime inference for closure with implicit types

提问人:Andrey Hanin 提问时间:2/2/2023 更新时间:2/2/2023 访问量:65

问:

这是微不足道的复制(截至 2 月 23 日的夜间 rustc):

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

错误是:

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

这没有意义,因为变量不是由 捕获的,而只是一个通过引用传递的参数。xclosure

为闭包参数提供显式引用可以解决问题,但不应该自动推断吗?_v: &_

是借用检查器的一些错误/限制吗?还是我在这里遗漏了一些更基本的东西?

Rust Closures 类型推理 生存期

评论


答:

5赞 pigeonhands 2/2/2023 #1

对我来说,这看起来像是类型推断的错误。

我认为正在发生的事情是

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
    }
}

但将闭包定义为

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

停止编译推断其生存期,并按应有的方式使用 hrtb

评论

2赞 pigeonhands 2/2/2023
打开了一个问题
1赞 pigeonhands 2/2/2023
我绝对似乎是一个推断的生存期问题,因为进入与闭包定义相同的范围也解决了它。play.rust-lang.org/......a
0赞 Chayim Friedman 2/2/2023
这可能是一个错误,但这是一个众所周知的错误,修复并不容易。请注意,有时甚至将参数声明为引用也不起作用;对于这些情况,我们有不稳定的语法。for<'a> |v: &'a i32|