为什么这辈子不能超过关闭?

时间:2018-09-11 01:41:28

标签: rust lifetime

我正在追踪a compiler bug,发现以下example

trait Lt<'a> {
    type T;
}

impl<'a> Lt<'a> for () {
    type T = &'a ();
}

fn test() {
    let _: fn(<() as Lt<'_>>::T) = |_: &'static ()| {};
}

fn main() {
    test();
}

我希望上面的内容能够编译,因为我给出了Lt<'_>Lt<'static>的提示,因此一切正常,但是出现以下错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/main.rs:10:53
   |
10 |     let _: fn(<() as Lt<'_>>::T) = |_: &'static ()| {};
   |                                                     ^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 10:36...
  --> src/main.rs:10:36
   |
10 |     let _: fn(<() as Lt<'_>>::T) = |_: &'static ()| {};
   |                                    ^^^^^^^^^^^^^^^^^^^
   = note: ...so that the types are compatible:
           expected Lt<'_>
              found Lt<'_>
   = note: but, the lifetime must be valid for the static lifetime...
   = note: ...so that the types are compatible:
           expected &()
              found &'static ()

“首先,生命周期不能超过匿名生命周期2”背后的逻辑是什么?在我查看错误的一个变体时,如果原因不明确,我们可以尝试修复它。

工作变化

fn test() {
    let _: fn(<() as Lt<'static>>::T) = |_: &'_ ()| {};
}

1 个答案:

答案 0 :(得分:1)

下面的代码片段是您的情况的简化,它有助于我理解 在您的代码中使用'static生命周期声明时,有关编译错误的问题。

struct Foo {
}

fn _test_ok() {

    // myf is declared as a function pointer that accepts
    // a reference with some generic lifetime  
    let myf: fn(&'_ Foo);

    // with this definition ...
    myf = |_arg: &'_ Foo| {};

    // this local value works as expected
    let local_foo: Foo = Foo {};

    myf(&local_foo);
}

fn _test_static_fail() {

    let myf: fn(&'_ Foo);

    // suppose this myf() definition ...
    myf = |_arg: &'static Foo| {};

    // this local value is compatible with myf() declaration ...
    let local_foo: Foo = Foo {};

    // so theoretically it is usable here: 
    myf(&local_foo);

    // but this is clearly not possible because the anomymous lifetime region where 
    // local_foo lives does not outlive the 'static lifetime required
    // when defining myf()   
}


static FOO: Foo = Foo {};

fn _test_static_flipped() {

    // As you have already discovered
    let myf: fn(&'static Foo) = |arg: &'_ Foo| {};

    // this works because ...
    // 1. FOO is a static value and it is compatible with myf() definition and
    // 2. 'static lifetime outlives every other lifetime  
    myf(&FOO);
}

fn main() {}