Reputation: 10426
I am chasing a compiler bug and found the following 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();
}
I expect the above to compile as I gave a hint for Lt<'_>
to be Lt<'static>
and so everything should be fine, but I get the following error:
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 ()
What is the logic behind "first, the lifetime cannot outlive the anonymous lifetime #2"? As I am looking at a variation of a bug, if the reason is not solid we can attempt to fix it.
fn test() {
let _: fn(<() as Lt<'static>>::T) = |_: &'_ ()| {};
}
Upvotes: 1
Views: 410
Reputation: 18923
The code fragments below are a semplification of your case, it helped me to understand
the issue about the compilation error when using the 'static
lifetime declaration in your code.
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() {}
Upvotes: 1