我正在追踪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) = |_: &'_ ()| {};
}
答案 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() {}