带有返回impl trait的泛型函数的“借入的值寿命不足”

Dan*_*bos 7 generics rust borrow-checker

我从此Rust代码收到意外错误:

struct Container<'a> {
    x: &'a i32,
}

trait Reply {}
impl Reply for i32 {}

fn json<T>(_val: &T) -> impl Reply {
    3
}

fn f() -> impl Reply {
    let i = 123;
    let a = Container { x: &i };
    json(&a)
}
Run Code Online (Sandbox Code Playgroud)

操场

错误是:

error[E0597]: `i` does not live long enough
  --> src/lib.rs:14:28
   |
12 | fn f() -> impl Reply {
   |           ---------- opaque type requires that `i` is borrowed for `'static`
13 |     let i = 123;
14 |     let a = Container { x: &i };
   |                            ^^ borrowed value does not live long enough
15 |     json(&a)
16 | }
   | - `i` dropped here while still borrowed
Run Code Online (Sandbox Code Playgroud)

为什么?

如果我将声明更改json()为以下两个版本之一,则代码将编译:

fn json(val: &Container) -> impl Reply
Run Code Online (Sandbox Code Playgroud)
fn json<T>(val: &T) -> i32
Run Code Online (Sandbox Code Playgroud)

只有当类型参数和返回的特征对象同时存在时,编译器才会拒绝代码。

这是我们遇到的一个实际问题的减少warp::reply::json(),但是我希望总体上理解它。

Alo*_*oso 1

当函数的参数和返回类型是泛型时,Rust 编译器假定返回类型可能会借用参数。这就是为什么它假设f()返回一个引用局部变量的值i

我不完全确定,但我认为这是理想的,因为有人可以实现Reply一种会出现问题的类型。

编辑:由于错误,这不起作用。GitHub 上已经报道过这一情况。