Hi everyone, this might be a basic question about lifetimes but I wanted to make sure if I understand it properly. I have two questions about the code snippet at the bottom:
(part 1): are the function signatures foo and bar below equivalent? If there is no relation between 'a and 'b, does it always mean 'b can be replaced by 'static? I cannot think of a reason why not. bar's function signature is more readable than foo's. If they are equivalent, I expected clippy to suggest writing in bar form, but I did not get any warnings with clippy.
(part 2): Why doesn't let _: T1 = baz throw a compile error? From what I understand, T1 is a function that takes a Foo with some lifetime 'a as input and returns a Foo that can live forever. Clearly baz does not define such a function. Is there something wrong with my understanding?
struct Foo<'a>(#[allow(unused)] &'a str);
fn foo<'a, 'b>(_a: Foo<'a>) -> Foo<'b> {
Foo("")
}
fn bar<'a>(_a: Foo<'a>) -> Foo<'static> {
Foo("")
}
fn baz<'a>(_a: Foo<'a>) -> Foo<'a> {
Foo("")
}
type T1<'a> = fn(Foo<'a>) -> Foo<'static>;
type T2<'a> = fn(Foo<'a>) -> Foo<'a>;
fn main() {
let s = String::from("abc");
let x = Foo(s.as_str());
let y = Foo(s.as_str());
let _z = Foo(s.as_str());
// part 1
let _: Foo<'static> = foo(x);
let _: Foo<'static> = bar(y);
// let _: Foo<'static> = baz(_z); // error
// part 2
let _: T1 = foo;
let _: T2 = foo;
let _: T1 = bar;
let _: T2 = bar;
let _: T1 = baz;
let _: T2 = baz;
}
Because T1 is an incomplete type, that assignment unifies to let _: T1<'static> = baz; // fn(Foo<'static>) -> Foo<'static>
You meant type T1 = for<'a> fn(Foo<'a>) -> Foo<'static> probably.
i.e. the confusion is the difference between "there exists an input lifetime for which 'static can be returned" and "for all input lifetimes 'static can be returned".