fact 1 : you are unable to return reference(s) of new object(s) from a function.
fact 2 : so the returned reference(s) must be one(s) of the passed in.
but there is an imperfect , in the following example , c is in fact a reference to G, but compiler think it is a reference of a, so can not compile because of A.
struct S(u8);
static G : S = S(1);
fn first(i :&S) ->&S {
&G
}
fn main() {
let mut a = S(0);
let c = first(&a);
a = S(0); // A
c;
}
The reason for this is that you did not put lifetime annotions to first, so the compiler infers them to be first(i: &'a S) -> &'a S, connecting the lifetimes of the input parameter and the output parameter, leading to the error you're observing. Changing first to first(i: &S) -> &'s static S will disentangle this in the way you're intending to and make the code compile.
based on the 2 facts , it is possible to eliminate the use of lifetime annotation , for example,
struct S(u8);
fn first(i :&S, j :&S , k :&S) ->&S {
// return one of the i j k
}
fn main() {
let (a,b,c) = (S(0),S(1),S(2));
let d = first(&a,&b,&c); // we do not care about
// which one will return
...
d;
// but just stretch the lifetimes of a b c
// beyond the last usage of d blindly
...
}
this solution may not be efficient , but can eliminate the lifetime annotation .
I'm not exactly sure what you're saying here. I explained why your first example wouldn't compile, and how to fix it. Based on this, your "fact 2" needs to be changed to "... must be one(s) of the passed in or 'static". Not a huge change, granted, but important in cases like this.
Now, what you've posted after that doesn't compile, but I don't understand what you want to express. Yes, you can eliminate lifetime annotations indeed, it's called lifetime elision. It doesn't kick in in this case, so are you saying you'd expect it to? Or are you saying that somehow the lifetimes should be extended so it all fits together? In your example though, "a b c" do indeed live until main finishes, so there's no usefull extension to be had.