为什么这一生不会比关闭更长寿?

问题描述 投票:1回答:1

我正在追逐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”的逻辑是什么?当我正在查看错误的变体时,如果原因不牢固,我们可以尝试修复它。

Working variation

fn test() {
    let _: fn(<() as Lt<'static>>::T) = |_: &'_ ()| {};
}
rust lifetime
1个回答
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() {}
© www.soinside.com 2019 - 2024. All rights reserved.